Is there a way in OSGi to make sure only one things has access to a service at a time?
I have an interface that defines a device in a system. The d开发者_开发技巧evices are intented to be used by only one entity at a time. I would like to register each device as an OSGi service so others can access the devices through that mechanism (using Declarative Services or a service tracker). However, that mechanism as far as I know, allows all entities to request the same service.
Is there a way for only the first requester to get the service or using Declarative Services only have one service component become satisfied?
Use a ServiceFactory to implement the device service. You can then return a unique service object to each bundle and then use that object to serialize access. Alternately your ServiceFactory could return null to other bundles if there is any other bundle which currently has access to the service.
Using a ServiceFactory allows your service implementation to know what bundles are using the service and to exert some control over their use.
AFAIK you can't use DS to impose a single consumer policy.
At first glance a ServiceFactory might work and if it did would be the simplest way to go.
However there's one caveat:
"The Framework caches the value returned (unless it is null), and will return the same service object on any future call to BundleContext.getService for the same bundle. This means the Framework must not allow this method to be concurrently called for the same bundle"
So I think it will fail in the following scenario:
Given Bundle A, Service S and Bundle B;
A gets S, then A ungets S, Bgets S, then A gets S.
The framework's cache may well interfere and give A the cached S even thought it is already held by B.
The only alternative I can think of is to use a FindHook, though this a bit more low-level, and you'd probably want to implement the other hooks (EventHook, ListenerHook) for completeness.
Using the hooks you'll be able to mask the services availability to other bundles. Though as your hook will be holding state you'll want it in the same bundle as the device service so that it's impossible to stop the hook without stopping the device service's bundle.
精彩评论