/**
* Copyright (C) 2012 - present by OpenGamma Inc. and the OpenGamma group of companies
*
* Please see distribution for license.
*/
package com.opengamma.engine.marketdata.live;
import java.lang.ref.WeakReference;
import java.util.Iterator;
import java.util.List;
import java.util.Set;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import com.google.common.collect.Lists;
import com.opengamma.engine.marketdata.availability.MarketDataAvailabilityFilter;
import com.opengamma.id.ExternalScheme;
import com.opengamma.livedata.LiveDataClient;
import com.opengamma.livedata.UserPrincipal;
import com.opengamma.util.ArgumentChecker;
/**
* Factory for building {@link LiveMarketDataProvider} instances.
*/
public class LiveDataFactory {
/** Logger */
private static final Logger s_logger = LoggerFactory.getLogger(LiveDataFactory.class);
/** Underlying source of the live data. */
private final LiveDataClient _liveDataClient;
/** For checking availability of live data. */
private final MarketDataAvailabilityFilter _availabilityFilter;
/**
* All providers created by this factory. They are accessed via weak references so they will be GCd when they're
* no longer being used by the engine. This will grow indefinitely unless {@link #resubscribe} is called. If that
* turns out to be a problem then a periodic task to clean out empty references will be needed.
*/
private final List<WeakReference<InMemoryLKVLiveMarketDataProvider>> _providers = Lists.newArrayList();
/** Lock for accessing the list of providers. */
private final Object _providerListLock = new Object();
/**
* Creates a new factory.
*
* @param liveDataClient the live data client to use to source data values
* @param availabilityFilter the filter describing which values to source from this live data client
*/
public LiveDataFactory(final LiveDataClient liveDataClient, final MarketDataAvailabilityFilter availabilityFilter) {
ArgumentChecker.notNull(liveDataClient, "liveDataClient");
ArgumentChecker.notNull(availabilityFilter, "availabilityFilter");
_liveDataClient = liveDataClient;
_availabilityFilter = availabilityFilter;
}
/* package */ LiveMarketDataProvider create(final UserPrincipal user) {
InMemoryLKVLiveMarketDataProvider provider =
new InMemoryLKVLiveMarketDataProvider(_liveDataClient, _availabilityFilter, user);
synchronized (_providerListLock) {
_providers.add(new WeakReference<>(provider));
}
return provider;
}
/**
* If a data provider becomes available this method will be invoked with the schemes handled by the provider.
* This gives market data providers the opportunity to reattempt previously failed subscriptions.
* @param schemes The schemes for which market data subscriptions should be reattempted.
*/
/* package */ void resubscribe(Set<ExternalScheme> schemes) {
synchronized (_providerListLock) {
s_logger.info("Telling providers to resubscribe to data for schemes: {}", schemes);
for (Iterator<WeakReference<InMemoryLKVLiveMarketDataProvider>> it = _providers.iterator(); it.hasNext(); ) {
WeakReference<InMemoryLKVLiveMarketDataProvider> ref = it.next();
InMemoryLKVLiveMarketDataProvider provider = ref.get();
if (provider != null) {
provider.resubscribe(schemes);
} else {
it.remove();
}
}
}
}
}