use of io.scalecube.transport.Message in project scalecube by scalecube.
the class ServiceDispatcher method onServiceRequest.
private void onServiceRequest(final Message request) {
Optional<ServiceInstance> serviceInstance = registry.getLocalInstance(serviceRequest(request), serviceMethod(request));
DispatchingFuture result = DispatchingFuture.from(sender, request);
try {
if (serviceInstance.isPresent() && serviceInstance.get() instanceof LocalServiceInstance) {
LocalServiceInstance instance = (LocalServiceInstance) serviceInstance.get();
Method method = instance.getMethod(request);
if (method.getReturnType().equals(CompletableFuture.class)) {
result.complete(serviceInstance.get().invoke(request));
} else if (method.getReturnType().equals(Observable.class) && !subscriptions.contains(request.correlationId())) {
final String cid = request.correlationId();
Subscription subscription = serviceInstance.get().listen(request).doOnCompleted(() -> {
subscriptions.unsubscribe(cid);
}).doOnTerminate(() -> {
subscriptions.unsubscribe(cid);
}).subscribe(onNext -> {
sender.send(request.sender(), onNext);
});
if (!subscription.isUnsubscribed()) {
subscriptions.put(request.correlationId(), new ServiceSubscription(cid, subscription, sender.cluster().member().id()));
}
}
} else {
result.completeExceptionally(new IllegalStateException("Service instance is was not found: " + request.qualifier()));
}
} catch (Exception ex) {
result.completeExceptionally(ex);
}
}
use of io.scalecube.transport.Message in project scalecube by scalecube.
the class FailureDetectorImpl method onPing.
/**
* Listens to PING message and answers with ACK.
*/
private void onPing(Message message) {
LOGGER.trace("Received Ping: {}", message);
PingData data = message.data();
Member localMember = membership.member();
if (!data.getTo().id().equals(localMember.id())) {
LOGGER.warn("Received Ping to {}, but local member is {}", data.getTo(), localMember);
return;
}
String correlationId = message.correlationId();
Message ackMessage = Message.withData(data).qualifier(PING_ACK).correlationId(correlationId).build();
LOGGER.trace("Send PingAck to {}", data.getFrom().address());
transport.send(data.getFrom().address(), ackMessage);
}
use of io.scalecube.transport.Message in project scalecube by scalecube.
the class GossipProtocolImpl method spreadGossipsTo.
private void spreadGossipsTo(Member member) {
// Select gossips to send
List<Gossip> gossipsToSend = selectGossipsToSend(member);
if (gossipsToSend.isEmpty()) {
// nothing to spread
return;
}
// Send gossip request
Message gossipReqMsg = buildGossipRequestMessage(gossipsToSend);
transport.send(member.address(), gossipReqMsg);
}
use of io.scalecube.transport.Message in project scalecube by scalecube.
the class MembershipProtocolImpl method onFailureDetectorEvent.
/**
* Merges FD updates and processes them.
*/
private void onFailureDetectorEvent(FailureDetectorEvent fdEvent) {
MembershipRecord r0 = membershipTable.get(fdEvent.member().id());
if (r0 == null) {
// member already removed
return;
}
if (r0.status() == fdEvent.status()) {
// status not changed
return;
}
LOGGER.debug("Received status change on failure detector event: {}", fdEvent);
if (fdEvent.status() == ALIVE) {
// TODO: Consider to make more elegant solution
// Alive won't override SUSPECT so issue instead extra sync with member to force it spread alive with inc + 1
Message syncMsg = prepareSyncDataMsg(SYNC, null);
transport.send(fdEvent.member().address(), syncMsg);
} else {
MembershipRecord r1 = new MembershipRecord(r0.member(), fdEvent.status(), r0.incarnation());
updateMembership(r1, MembershipUpdateReason.FAILURE_DETECTOR_EVENT);
}
}
use of io.scalecube.transport.Message in project scalecube by scalecube.
the class MembershipProtocolImpl method doInitialSync.
// ================================================
// ============== Action Methods ==================
// ================================================
private CompletableFuture<Void> doInitialSync() {
LOGGER.debug("Making initial Sync to all seed members: {}", seedMembers);
if (seedMembers.isEmpty()) {
schedulePeriodicSync();
return CompletableFuture.completedFuture(null);
}
CompletableFuture<Void> syncResponseFuture = new CompletableFuture<>();
// Listen initial Sync Ack
String cid = memberRef.get().id();
transport.listen().observeOn(scheduler).filter(msg -> SYNC_ACK.equals(msg.qualifier())).filter(msg -> cid.equals(msg.correlationId())).filter(this::checkSyncGroup).take(1).timeout(config.getSyncTimeout(), TimeUnit.MILLISECONDS, scheduler).subscribe(message -> {
SyncData syncData = message.data();
LOGGER.info("Joined cluster '{}': {}", syncData.getSyncGroup(), syncData.getMembership());
onSyncAck(message, true);
schedulePeriodicSync();
syncResponseFuture.complete(null);
}, throwable -> {
LOGGER.info("Timeout getting initial SyncAck from seed members: {}", seedMembers);
schedulePeriodicSync();
syncResponseFuture.complete(null);
});
Message syncMsg = prepareSyncDataMsg(SYNC, cid);
seedMembers.forEach(address -> transport.send(address, syncMsg));
return syncResponseFuture;
}
Aggregations