public Serializer serializer() { return service.serializer(); }
/** * Creates a service session. * * @param sessionId the session to create * @param memberId the owning node ID * @return the service session */ public PrimaryBackupSession createSession(long sessionId, MemberId memberId) { PrimaryBackupSession session = new PrimaryBackupSession(SessionId.from(sessionId), memberId, service.serializer(), this); if (sessions.putIfAbsent(sessionId, session) == null) { service.register(session); } return session; }
/** * Gets or creates a session. * * @param sessionId the session identifier * @return the session */ private Session getOrCreateSession(SessionId sessionId) { Session session = sessions.get(sessionId); if (session == null) { session = new LocalSession(sessionId, name(), type(), null, service.serializer()); sessions.put(session.sessionId(), session); service.register(session); } return session; }
@Override public CompletableFuture<RestoreResponse> restore(RestoreRequest request) { logRequest(request); if (request.term() != context.currentTerm()) { return CompletableFuture.completedFuture(logResponse(RestoreResponse.error())); } HeapBuffer buffer = HeapBuffer.allocate(); try { Collection<PrimaryBackupSession> sessions = context.getSessions(); buffer.writeInt(sessions.size()); for (Session session : sessions) { buffer.writeLong(session.sessionId().id()); buffer.writeString(session.memberId().id()); } context.service().backup(new DefaultBackupOutput(buffer, context.service().serializer())); buffer.flip(); byte[] bytes = buffer.readBytes(buffer.remaining()); return CompletableFuture.completedFuture( RestoreResponse.ok(context.currentIndex(), context.currentTimestamp(), bytes)) .thenApply(this::logResponse); } finally { buffer.release(); } }
/** * Requests a restore from the primary. */ private void requestRestore(MemberId primary) { context.protocol().restore(primary, RestoreRequest.request(context.descriptor(), context.currentTerm())) .whenCompleteAsync((response, error) -> { if (error == null && response.status() == PrimaryBackupResponse.Status.OK) { context.resetIndex(response.index(), response.timestamp()); Buffer buffer = HeapBuffer.wrap(response.data()); int sessions = buffer.readInt(); for (int i = 0; i < sessions; i++) { context.getOrCreateSession(buffer.readLong(), MemberId.from(buffer.readString())); } context.service().restore(new DefaultBackupInput(buffer, context.service().serializer())); operations.clear(); } }, context.threadContext()); } }
maxTimeout, sessionTimestamp, service.serializer(), this, raft, service.register(sessions.addSession(session)); service.restore(new DefaultBackupInput(reader, service.serializer()));
/** * Takes a snapshot of the service state. */ public void takeSnapshot(SnapshotWriter writer) { log.debug("Taking snapshot {}", writer.snapshot().index()); // Serialize sessions to the in-memory snapshot and request a snapshot from the state machine. writer.writeLong(primitiveId.id()); writer.writeString(primitiveType.name()); writer.writeString(serviceName); writer.writeLong(currentIndex); writer.writeLong(currentTimestamp); writer.writeLong(timestampDelta); writer.writeInt(sessions.getSessions().size()); for (RaftSession session : sessions.getSessions()) { writer.writeLong(session.sessionId().id()); writer.writeString(session.memberId().id()); writer.writeString(session.readConsistency().name()); writer.writeLong(session.minTimeout()); writer.writeLong(session.maxTimeout()); writer.writeLong(session.getLastUpdated()); writer.writeLong(session.getRequestSequence()); writer.writeLong(session.getCommandSequence()); writer.writeLong(session.getEventIndex()); writer.writeLong(session.getLastCompleted()); } service.backup(new DefaultBackupOutput(writer, service.serializer())); }