【问题标题】:Long lasting Declarative Service activate method持久声明式服务激活方法
【发布时间】:2019-12-06 02:58:52
【问题描述】:

我试图了解from the OSGi specs 在激活方法无限期阻塞但我没有找到答案的情况下会发生什么。另一方面,Felix SCR 似乎有 ds.lock.timeout.millisecondsds.stop.timeout.milliseconds 属性来管理激活/停用超时,对吧?

问题:

  • 为什么 OSGi 规范没有提及激活/停用死锁管理?
  • 如果 DS 需要更多时间来运行其激活方法,增加默认 SCR ds.lock.timeout.milliseconds 值是否明智?还是完全避免激活方法并在专用线程中使用context.registerService“手动”注册服务更好?

【问题讨论】:

    标签: osgi osgi-ds


    【解决方案1】:

    按照视频OSGI Best Practices by Eclipse Foundation 中的建议,您可以在单独的线程中开始长期工作,然后手动注册您的服务。

    @Activate
    public void activate(BundleContext context) {
        this.context = context;
        this.reg = CompletableFuture.supplyAsync(this::longRunning);
    }
    
    @Deactivate
    public void deactivate() {
        this.reg.thenAcceptAsync(ServiceRegistration::unregister);
    }
    
    private ServiceRegistration<TaskService> longRunning() {
        // long running call
        return context.registerService(TaskService.class, this, new Hashtable<String, String>());
    }
    

    【讨论】:

      【解决方案2】:

      如果您的初始化时间较长,请标记组件immediate。在 activate 方法中,您启动后台初始化。当你的服务被调用时,你会阻塞直到初始化完成。 (Promise 非常适合这种技术。)

      @Component(immediate=true)
      public class FooImpl implements Foo {
         Promise<Foo>  promise;
      
         @Activate void activate() { promise = begin(); }
      
         @Override
         public void foo() { promise.get().foo(); }
      }
      

      这种技术的优点是它允许许多初始化并行进行。

      您需要的委托有点难看。如果性能不是很重要,您可以轻松创建一个代理来完成实际工作。

      【讨论】:

        【解决方案3】:

        据我所知,唯一安全的方法是在您的异步代码完成时在 activate 中生成另一个线程并注册服务。

        【讨论】:

          猜你喜欢
          • 2011-08-08
          • 1970-01-01
          • 1970-01-01
          • 2022-11-27
          • 2021-11-22
          • 2020-11-10
          • 1970-01-01
          • 1970-01-01
          • 2017-01-08
          相关资源
          最近更新 更多