@Override public void call() { instanceInfoById.put(newInfo.getId(), newInfo); } });
@Override public void call() { instanceInfoById.put(instanceInfo.getId(), instanceInfo); } });
private void evict() { if (!replicationLoop) { logger.info("Replication channel disconnected; putting all registrations from the channel in the eviction queue"); for (InstanceInfo instanceInfo : instanceInfoById.values()) { logger.info("Replication channel disconnected; adding instance {} to the eviction queue", instanceInfo.getId()); evictionQueue.add(instanceInfo, replicationSource); } } } });
@Override protected ChannelHandler<ReplicationChannel> getChannelHandler() { if (registryReplicator == null) { registryReplicator = new RegistryReplicator(ownInstanceInfo.getId(), eurekaRegistry); } return registryReplicator; } };
@Override public Observable<Void> update(InstanceInfo instanceInfo) { if (shutdown) { return Observable.error(new IllegalStateException("Registration handler is already shutdown.")); } final RegistrationChannel registrationChannel = instanceIdVsChannel.get(instanceInfo.getId()); if (null == registrationChannel) { logger.info("Instance: %s is not registered. Relaying update as register.", instanceInfo); return register(instanceInfo); // Be more acceptable to errors from user. } return registrationChannel.update(instanceInfo); }
@Override public void onNext(InstanceInfo instanceInfo) { totalCount.incrementAndGet(); newSnapshot.put(instanceInfo.getId(), instanceInfo); if (currentSnapshot.containsKey(instanceInfo.getId())) { InstanceInfo older = currentSnapshot.get(instanceInfo.getId()); if (!older.equals(instanceInfo)) { Set<Delta<?>> deltas = older.diffNewer(instanceInfo); registry.update(instanceInfo, deltas); updateCount.incrementAndGet(); } } else { registry.register(instanceInfo); registerCount.incrementAndGet(); } } });
private void evictIfRegistered() { if (state.get() == STATES.Registered) { logger.info("Connection terminated without unregister; adding instance {} to eviction queue", currentInfo.getId()); evictionQueue.add(currentInfo, Source.localSource()); } } });
@Override public Observable<Void> register(InstanceInfo instanceInfo) { if (shutdown) { return Observable.error(new IllegalStateException("Registration handler is already shutdown.")); } final RegistrationChannel newChannel = channelFactory.newRegistrationChannel(); final RegistrationChannel existing = instanceIdVsChannel.putIfAbsent(instanceInfo.getId(), newChannel); if (null != existing) { return existing.update(instanceInfo); // Be more acceptable to failure in contract adherence from the user. // If it is the same instance as existing, the server should not // generate unnecessary notifications. } return newChannel.register(instanceInfo); }
/** * For an AddInstance msg, * - if it does not exist in cache, this is an Add Notification to the store * - if it exist in cache but had a different version, this is a modify notification to the store. * For simplicity we treat this as an add if the new msg have a GREATER version number, * and ignore it otherwise */ private ChangeNotification<InstanceInfo> addMessageToChangeNotification(AddInstance msg) { ChangeNotification<InstanceInfo> notification = null; InstanceInfo incoming = msg.getInstanceInfo(); InstanceInfo cached = idVsInstance.get(incoming.getId()); if (cached == null) { idVsInstance.put(incoming.getId(), incoming); notification = new ChangeNotification<>(ChangeNotification.Kind.Add, incoming); } else if (incoming.getVersion() <= cached.getVersion()) { logger.debug("Skipping <= version of the instanceInfo. Cached: {}, Incoming: {}", cached, incoming); } else { logger.debug("Received newer version of an existing instanceInfo as Add"); idVsInstance.put(incoming.getId(), incoming); notification = new ChangeNotification<>(ChangeNotification.Kind.Add, incoming); } return notification; }
@Override public Observable<Void> unregister(InstanceInfo instanceInfo) { if (shutdown) { return Observable.error(new IllegalStateException("Registration handler is already shutdown.")); } final RegistrationChannel registrationChannel = instanceIdVsChannel.remove(instanceInfo.getId()); if (null == registrationChannel) { logger.info("Instance: %s is not registered. Ignoring unregister", instanceInfo); return Observable.empty(); // Be more acceptable to errors from user as unregister for non-existent instance is a no-op. } return registrationChannel.unregister().doOnTerminate(new Action0() { @Override public void call() { // Since we do not reuse the channel, we must shut it down with the underlying connection. registrationChannel.close(); } }); }
private static String extractInstanceId(InstanceInfo instanceInfo) { if (instanceInfo != null && instanceInfo.getDataCenterInfo() != null && AwsDataCenterInfo.class.isAssignableFrom(instanceInfo.getDataCenterInfo().getClass())) { final AwsDataCenterInfo dataCenterInfo = (AwsDataCenterInfo) instanceInfo.getDataCenterInfo(); return dataCenterInfo.getInstanceId(); } return instanceInfo.getId(); }
@Override public Observable<Void> register(InstanceInfo instanceInfo) { internalStore.put(instanceInfo.getId(), instanceInfo); notificationSubject.onNext(new ChangeNotification<>(Kind.Add, instanceInfo)); return Observable.empty(); }
@Override public Observable<Void> unregister(InstanceInfo instanceInfo) { InstanceInfo removed = internalStore.remove(instanceInfo.getId()); if (removed != null) { notificationSubject.onNext(new ChangeNotification<>(Kind.Delete, instanceInfo)); } return Observable.empty(); }
@Override public Observable<Status> unregister(final InstanceInfo instanceInfo, final Source source) { final MultiSourcedDataHolder<InstanceInfo> currentHolder = internalStore.get(instanceInfo.getId()); if (currentHolder == null) { return Observable.just(Status.RemoveExpired); } Observable<Status> result = currentHolder.remove(source, instanceInfo).doOnNext(new Action1<Status>() { @Override public void call(Status status) { if (status != Status.RemoveExpired) { metrics.incrementUnregistrationCounter(source.getOrigin()); } } }); return subscribeToUpdateResult(result); }
@PostConstruct public void startRegistryAuditing() { InstanceInfo auditServer = serverIdentity.resolve().toBlocking().firstOrDefault(null); final String auditServerId = auditServer == null ? null : auditServer.getId(); // TODO: this should be only Origin.Local, but since bridge works on replication channel we would not audit eureka 1.0 entries. registry.forInterest(Interests.forFullRegistry()).subscribe(new Subscriber<ChangeNotification<InstanceInfo>>() { @Override public void onCompleted() { logger.warn("Registry auditing finished"); } @Override public void onError(Throwable e) { logger.warn("Registry auditing finished due to an error in interest channel subscription", e); } @Override public void onNext(ChangeNotification<InstanceInfo> notification) { AuditRecord record = AuditRecords.forChangeNotification(auditServerId, System.currentTimeMillis(), false, notification); auditService.write(record); } }); } }
@Override public Observable<Void> update(InstanceInfo updatedInfo, Set<Delta<?>> deltas) { InstanceInfo previous = internalStore.put(updatedInfo.getId(), updatedInfo); if (previous == null) { notificationSubject.onNext(new ChangeNotification<>(Kind.Add, updatedInfo)); } else { notificationSubject.onNext(new ModifyNotification<>(updatedInfo, deltas)); } return Observable.empty(); }
@Override public Observable<Status> register(final InstanceInfo instanceInfo, final Source source) { MultiSourcedDataHolder<InstanceInfo> holder = new NotifyingInstanceInfoHolder( internalStoreAccessor, notificationSubject, invoker, instanceInfo.getId()); Observable<Status> result = holder.update(source, instanceInfo).doOnNext(new Action1<Status>() { @Override public void call(Status status) { if (status != Status.AddExpired) { metrics.incrementRegistrationCounter(source.getOrigin()); } } }); return subscribeToUpdateResult(result); }
Builder newBuilder() { return new Builder() .withId(this.baseInstanceInfo.getId()) .withVersion(this.baseInstanceInfo.getVersion() + 1); } }
@Override public Observable<Status> update(InstanceInfo updatedInfo, Set<Delta<?>> deltas, final Source source) { MultiSourcedDataHolder<InstanceInfo> holder = new NotifyingInstanceInfoHolder( internalStoreAccessor, notificationSubject, invoker, updatedInfo.getId()); Observable<Status> result = holder.update(source, updatedInfo).doOnNext(new Action1<Status>() { @Override public void call(Status status) { if (status != Status.AddExpired) { metrics.incrementUpdateCounter(source.getOrigin()); } } }); return subscribeToUpdateResult(result); }