Space constraints.

> On 19 Sep 2013, at 18:55, Peter Kriens <[email protected]> wrote:
> 
> Why not use DS?
> 
> 
>> On 19 sep. 2013, at 18:02, Daniel McGreal wrote:
>> 
>> Hi OSGi-devs,
>> 
>> I have a question about utilising ServiceTracker to manage a class's 
>> dependencies and blocking during the call, which I confess is probably well 
>> trodden ground but for which I can't apparently find the right Google 
>> terminology. Perhaps because I've been, until now, coddled by higher-level 
>> service dynamism, like Blueprint.
>> 
>> I have a java.util.logging.Handler whose publish method needs a couple of 
>> OSGi services to operate. Any LogRecords that are published during a refresh 
>> of either of the dependencies should not be lost and should be reattempted 
>> when services resume (which in practice might be a long time, the device 
>> this application targets is incredibly primitive).
>> 
>> Currently I have the Activator and Handler in the same implementation (which 
>> seems like it might be bad practice, if it is, I'd love to know why). Here's 
>> a trimmed down version, with just one dependency:
>> 
>> public class RemoteLoggingHandler extends Handler implements BundleActivator 
>> {
>>      private volatile Channel channel;
>>      
>>      private ServiceTracker<IAmqpChannelProvider, IAmqpChannelProvider> 
>> channelProviderTracker;
>>      
>>      @Override public void start(BundleContext context) throws Exception {   
>>         
>>              channelProviderTracker = new 
>> ServiceTracker<IAmqpChannelProvider, IAmqpChannelProvider>(context, 
>> IAmqpChannelProvider.class, null){
>>                      @Override public IAmqpChannelProvider 
>> addingService(ServiceReference<IAmqpChannelProvider> reference) {
>>                              IAmqpChannelProvider channelProvider = 
>> super.addingService(reference);
>>                              try {
>>                                      channel = 
>> channelProvider.createChannel();
>>                                      //Some initialisation, can happen once 
>> or multiple times, no problem.
>>                                      
>> channel.exchangeDeclare(LoggingConstants.LOGGING_EXG_NAME, "topic", true);
>>                                      notifyAll();
>>                              } catch (IOException e) {
>>                                      e.printStackTrace();
>>                              }
>>                              return channelProvider;
>>                      }
>>                      
>>                      @Override public synchronized void 
>> modifiedService(ServiceReference<IAmqpChannelProvider> reference, 
>> IAmqpChannelProvider service) {
>>                              removedService(reference, service);
>>                              addingService(reference);
>>                      }
>>                      
>>                      @Override public void 
>> removedService(ServiceReference<IAmqpChannelProvider> reference, 
>> IAmqpChannelProvider service) {
>>                              super.removedService(reference, service);
>>                              channel = null;
>>                      }
>>              };
>>              channelProviderTracker.open();
>>                              
>>              LogManager.getLogManager().getLogger("").addHandler(this);
>>      }
>> 
>>      @Override public void stop(BundleContext context) throws Exception {
>>              LogManager.getLogManager().getLogger("").removeHandler(this);
>>      }
>> 
>>      @Override
>>      public void publish(LogRecord record) {
>>              try {
>>                      synchronized (channelProviderTracker) {
>>                              while(channel == null) 
>> channelProviderTracker.wait();
>>                              
>>                              
>> channel.basicPublish(LoggingConstants.LOGGING_EXG_NAME, 
>> record.getLoggerName(),
>>                                              null, 
>> record.getMessage().getBytes());
>>                      }
>>              } catch (Exception e) {
>>                  reportError(null, e, ErrorManager.WRITE_FAILURE);
>>                  return;
>>              }
>>      }
>>      
>>      //Some boilerplate....
>>      
>>      @Override public void flush() {} //Unnecessary.
>> 
>>      @Override
>>      public void close() throws SecurityException {
>>              flush();
>>              try {
>>                      channel.close();
>>              } catch (IOException e) {
>>                      reportError("Amqp channel could not be closed", e, 
>> ErrorManager.CLOSE_FAILURE);                 
>>              }
>>      }
>>      
>> }
>> 
>> I don't feel that I've been successful. The channel member field can still 
>> go to null while it's being used in publish, and probably many other 
>> problems I've missed! Can anyone point out to me either the standard 
>> procedure for this, or any comments on my above attempt?
>> 
>> Many thanks,
>> Dan.
>> 
>> 
>> _______________________________________________
>> OSGi Developer Mail List
>> [email protected]
>> https://mail.osgi.org/mailman/listinfo/osgi-dev
> 
> _______________________________________________
> OSGi Developer Mail List
> [email protected]
> https://mail.osgi.org/mailman/listinfo/osgi-dev
_______________________________________________
OSGi Developer Mail List
[email protected]
https://mail.osgi.org/mailman/listinfo/osgi-dev

Reply via email to