持久声明式服务激活方法

Long lasting Declarative Service activate method

我试图了解 from the OSGi specs 如果 activate 方法无限期阻塞会发生什么,但我没有找到答案。另一方面,它认为 Felix SCR 具有 ds.lock.timeout.millisecondsds.stop.timeout.milliseconds 属性来管理 activate/deactivate 超时,对吗?

问题:

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

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

@Component(immediate=true)
public class FooImpl implements Foo {
   Promise<Foo>  promise;

   @Activate void activate() { promise = begin(); }

   @Override
   public void foo() { promise.get().foo(); }
}

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

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

如本视频 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>());
}