All Downloads are FREE. Search and download functionalities are using the official Maven repository.

io.camunda.zeebe.transport.stream.impl.ClientStreamRegistration Maven / Gradle / Ivy

There is a newer version: 8.7.0-alpha1
Show newest version
/*
 * Copyright Camunda Services GmbH and/or licensed to Camunda Services GmbH under
 * one or more contributor license agreements. See the NOTICE file distributed
 * with this work for additional information regarding copyright ownership.
 * Licensed under the Camunda License 1.0. You may not use this file
 * except in compliance with the Camunda License 1.0.
 */
package io.camunda.zeebe.transport.stream.impl;

import io.atomix.cluster.MemberId;
import io.camunda.zeebe.util.buffer.BufferWriter;
import java.util.EnumSet;
import java.util.Set;
import java.util.UUID;
import java.util.concurrent.CompletionStage;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/**
 * Represents the registration state of remote stream from the client's point of view. Used
 * specifically to serialize the lifecycle of a stream and avoid concurrent, out of order,
 * registration and removal requests.
 *
 * 

This class is not thread safe, and expects to be always called from the same synchronization * context. */ final class ClientStreamRegistration { private static final Logger LOGGER = LoggerFactory.getLogger(ClientStreamRegistration.class); private final AggregatedClientStream stream; private final MemberId serverId; private State state = State.INITIAL; private CompletionStage pendingRequest; ClientStreamRegistration(final AggregatedClientStream stream, final MemberId serverId) { this.stream = stream; this.serverId = serverId; } UUID streamId() { return stream.streamId(); } LogicalId logicalId() { return stream.logicalId(); } MemberId serverId() { return serverId; } State state() { return state; } CompletionStage pendingRequest() { return pendingRequest; } void setPendingRequest(final CompletionStage pendingRequest) { this.pendingRequest = pendingRequest; } boolean transitionToAdding() { return transition(State.ADDING, EnumSet.of(State.INITIAL)); } void transitionToAdded() { if (transition(State.ADDED, EnumSet.of(State.ADDING))) { stream.add(serverId); } } boolean transitionToRemoving() { return transition(State.REMOVING, EnumSet.of(State.INITIAL, State.ADDING, State.ADDED)); } void transitionToRemoved() { if (transition(State.REMOVED, EnumSet.of(State.INITIAL, State.REMOVING))) { stream.remove(serverId); } } void transitionToClosed() { transition(State.CLOSED, EnumSet.allOf(State.class)); stream.remove(serverId); } private boolean transition(final State target, final Set allowed) { if (!allowed.contains(state)) { logSkippedTransition(target); return false; } state = target; LOGGER.trace("{} remote client stream {} on server {}", target, stream.streamId(), serverId); return true; } private void logSkippedTransition(final State target) { LOGGER.trace( "Skip {} transition of stream {} on {} as its state is {}", target, stream.streamId(), serverId, state); } /** * State transitions: * *

    *
  • INITIAL -> [ADDING, REMOVED] *
  • ADDING -> [ADDED, REMOVING] *
  • ADDED -> [REMOVING] *
  • REMOVING -> [REMOVED] *
  • REMOVED -> [] *
*/ enum State { INITIAL, ADDING, ADDED, REMOVING, REMOVED, CLOSED } }




© 2015 - 2024 Weber Informatics LLC | Privacy Policy