持久声明式服务激活方法
Long lasting Declarative Service activate method
我试图了解 from the OSGi specs 如果 activate 方法无限期阻塞会发生什么,但我没有找到答案。另一方面,它认为 Felix SCR 具有 ds.lock.timeout.milliseconds
和 ds.stop.timeout.milliseconds
属性来管理 activate/deactivate 超时,对吗?
问题:
- 为什么 OSGi 规范没有提到 activate/deactivate 死锁管理?
- 如果 DS 需要更多时间 运行 它的激活方法,增加默认 SCR
ds.lock.timeout.milliseconds
值是否明智?还是完全避免激活方法并在专用线程中使用 context.registerService
注册服务 "by hand" 更好?
据我所知,唯一安全的方法是在 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>());
}
我试图了解 from the OSGi specs 如果 activate 方法无限期阻塞会发生什么,但我没有找到答案。另一方面,它认为 Felix SCR 具有 ds.lock.timeout.milliseconds
和 ds.stop.timeout.milliseconds
属性来管理 activate/deactivate 超时,对吗?
问题:
- 为什么 OSGi 规范没有提到 activate/deactivate 死锁管理?
- 如果 DS 需要更多时间 运行 它的激活方法,增加默认 SCR
ds.lock.timeout.milliseconds
值是否明智?还是完全避免激活方法并在专用线程中使用context.registerService
注册服务 "by hand" 更好?
据我所知,唯一安全的方法是在 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>());
}