4

我试图从 OSGi 规范中了解在激活方法无限期阻塞的情况下应该发生什么,但我没有找到答案。另一方面,Felix SCR 具有 管理激活/停用超时的属性,对吗ds.lock.timeout.millisecondsds.stop.timeout.milliseconds

问题:

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

3 回答 3

4

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

于 2019-07-28T20:51:17.287 回答
1

如果你有一个很长的初始化,你标记组件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(); }
}

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

您需要的代表团有点丑陋。如果性能不是很重要,您可以轻松地创建一个代理来完成实际工作。

于 2019-07-29T09:13:56.987 回答
0

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

@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>());
}
于 2021-10-21T08:39:04.463 回答