public InstanceInfoInitStateHolder(Iterator<ChangeNotification<InstanceInfo>> initialRegistry, Interest<InstanceInfo> interest) { super(PauseableSubject.<ChangeNotification<InstanceInfo>>create()); this.bufferStartNotification = new StreamStateNotification<>(BufferState.BufferStart, interest); this.bufferEndNotification = new StreamStateNotification<>(BufferState.BufferEnd, interest); notificationMap = new ConcurrentHashMap<>(); while (initialRegistry.hasNext()) { ChangeNotification<InstanceInfo> next = initialRegistry.next(); notificationMap.put(next.getData().getId(), next); // Always Kind.Add } }
@Override public void call(Subscriber<? super ChangeNotification<T>> subscriber) { // We need to buffer all the changes while the init state is replayed. // Because new instance holder updates will be added while we replay them, they will be // partially visible by the subscriber. When we replay buffered real time updates, // they may overlap with what was already sent from the init holder. // TODO can we make this buffering cheaper? final PauseableSubject<ChangeNotification<T>> realTimeSubject = PauseableSubject.create(); realTimeSubject.pause(); realTimeSource.subscribe(realTimeSubject); realTimeSubject.mergeWith(Observable.from(initStateHolder).doOnCompleted(new Action0() { @Override public void call() { realTimeSubject.resume(); } })).subscribe(subscriber); } });
public SourcedEurekaRegistryImpl(IndexRegistry<InstanceInfo> indexRegistry, EurekaRegistryMetricFactory metricsFactory, Scheduler scheduler) { this.indexRegistry = indexRegistry; this.metrics = metricsFactory.getEurekaServerRegistryMetrics(); invoker = new NotifyingInstanceInfoHolder.NotificationTaskInvoker( metricsFactory.getRegistryTaskInvokerMetrics(), scheduler); internalStore = new ConcurrentHashMap<>(); pauseableSubject = PauseableSubject.create(); internalStoreAccessor = new MultiSourcedDataHolder.HolderStoreAccessor<NotifyingInstanceInfoHolder>() { @Override public void add(NotifyingInstanceInfoHolder holder) { internalStore.put(holder.getId(), holder); metrics.setRegistrySize(internalStore.size()); } @Override public NotifyingInstanceInfoHolder get(String id) { return internalStore.get(id); } @Override public void remove(String id) { internalStore.remove(id); metrics.setRegistrySize(internalStore.size()); } @Override public boolean contains(String id) { return internalStore.containsKey(id); } }; }