Package io.mats3

Interface MatsEndpoint<R,S>

All Superinterfaces:
MatsConfig.StartStoppable

public interface MatsEndpoint<R,S> extends MatsConfig.StartStoppable
Represents a Mats Endpoint - you create instances from the MatsFactory (or use the Spring integration).

Implementation Note: It shall be possible to use instances of MatsEndpoint as keys in a HashMap, i.e. their equals and hashCode should remain stable throughout the life of the MatsFactory - and similar instances but with different MatsFactory are not equals. Depending on the implementation, instance equality may be sufficient.

  • Method Details

    • getEndpointConfig

      MatsEndpoint.EndpointConfig<R,S> getEndpointConfig()
      Returns:
      the config for this endpoint. If endpoint is not yet started, you may invoke mutators on it.
    • getParentFactory

      MatsFactory getParentFactory()
      Returns:
      the parent MatsFactory.
    • stage

      <I> MatsStage<R,S,I> stage(Class<I> incomingClass, MatsEndpoint.ProcessLambda<R,S,I> processor)
      Adds a new stage to a multi-stage endpoint. If this is the last stage of a multi-stage endpoint, you must invoke finishSetup() afterwards - or you could instead use the lastStage(Class, ProcessReturnLambda) variant which does this automatically.
      Type Parameters:
      I - the type of the incoming DTO. The very first stage's incoming DTO is the endpoint's incoming DTO. If the special type MatsEndpoint.MatsObject, this stage can take any type.
      Parameters:
      processor - the lambda that will be invoked when messages arrive in the corresponding queue.
      See Also:
    • stage

      <I> MatsStage<R,S,I> stage(Class<I> incomingClass, Consumer<? super MatsStage.StageConfig<R,S,I>> stageConfigLambda, MatsEndpoint.ProcessLambda<R,S,I> processor)
      Variation of stage(Class, ProcessLambda) that can be configured "on the fly".
    • lastStage

      <I> MatsStage<R,S,I> lastStage(Class<I> incomingClass, MatsEndpoint.ProcessReturnLambda<R,S,I> processor)
      Adds the last stage to a multi-stage endpoint, which also finishes setup of the endpoint. Note that the last-stage concept is just a convenience that lets the developer reply from the endpoint with a return replyDTO statement - you may just as well add a standard stage, and invoke the MatsEndpoint.ProcessContext.reply(Object) method. Note: If using a normal stage as the last stage, you must remember to invoke finishSetup() afterwards, as that is then not done automatically.
      Type Parameters:
      I - the type of the incoming DTO. The very first stage's incoming DTO is the endpoint's incoming DTO. If the special type MatsEndpoint.MatsObject, this stage can take any type.
      Parameters:
      processor - the lambda that will be invoked when messages arrive in the corresponding queue.
    • lastStage

      <I> MatsStage<R,S,I> lastStage(Class<I> incomingClass, Consumer<? super MatsStage.StageConfig<R,S,I>> stageConfigLambda, MatsEndpoint.ProcessReturnLambda<R,S,I> processor)
      Variation of lastStage(Class, ProcessReturnLambda) that can be configured "on the fly".
    • getStages

      List<MatsStage<R,S,?>> getStages()
      Returns:
      a List of MatsStages, representing all the stages of the endpoint. The order is the same as the order in which the stages will be invoked. For single-staged endpoints and terminators, this list is of size 1.
    • finishSetup

      void finishSetup()
      Should be invoked when all stages has been added. Will automatically be invoked by invocation of lastStage(Class, ProcessReturnLambda), which again implies that it will be invoked when creating single-stage endpoints and terminators and subscription terminators.

      This sets the state of the endpoint to "finished setup", and will invoke start() on the endpoint, unless MatsFactory.holdEndpointsUntilFactoryIsStarted() has been invoked prior to creating the endpoint.

      You may implement "delayed start" of an endpoint by not invoking finishedSetup() after setting it up. Taking into account the first chapter of this JavaDoc, note that you must then only use the staged type of Endpoint setup, as the others implicitly invokes finishSetup(), and also not invoke lastStage on it as this also implicitly invokes finishSetup(). When setting an Endpoint up without calling finishSetup(), even when MatsFactory.start() is invoked, such a not-finished endpoint will then not be started. You may then later invoke finishSetup(), e.g. when any needed caches are finished populated, and the endpoint will then be finished and started.

      Another way to implement "delayed start" is to obviously just not create the endpoint until later: MatsFactory has no "that's it, now all endpoints must have been created"-lifecycle stage, and can fire up new endpoints until the JVM is dead.

    • start

      void start()
      Starts the endpoint (unless finishSetup() has NOT been invoked), invoking MatsStage.start() on any not-yet started stages of the endpoint (which should be all of them at application startup).
      Specified by:
      start in interface MatsConfig.StartStoppable
    • waitForReceiving

      boolean waitForReceiving(int timeoutMillis)
      Waits till all stages of the endpoint has entered their receive-loops, i.e. invokes MatsStage.waitForReceiving(int) on all MatsStages of the endpoint.

      Note: This method makes most sense for SubscriptionTerminators: These are based on MQ Topics, whose semantics are that if you do not listen right when someone says something, you will not hear it. This means that a SubscriptionTerminator will never receive a message that was sent before it had started the receive-loop. Thus, if you in a service-"boot" phase send a message whose result will come in to a SubscriptionTerminator, you will not receive this result if the receive-loop has not started. This is relevant for certain cache setups where you listen for event updates, and when "booting" the cache, you need to be certain that you have started receiving updates before asking for the "initial load" of the cache. It is also relevant for tools like the MatsFuturizer, which uses a node-specific Topic for the final reply message from the requested service; If the SubscriptionTerminator has not yet made it to the receive-loop, any replies will simply be lost and the future never completed.

      Note: Currently, this only holds for the initial start. If the entity has started the receive-loop at some point, it will always immediately return - even though it is currently stopped.

      Specified by:
      waitForReceiving in interface MatsConfig.StartStoppable
      Parameters:
      timeoutMillis - number of milliseconds before giving up the wait, returning false. 0 is indefinite wait, negative values are not allowed.
      Returns:
      whether it was started (i.e. true if successfully started listening for messages).
    • stop

      boolean stop(int gracefulShutdownMillis)
      Stops the endpoint, invoking MatsStage.stop(int) on all MatsStages.
      Specified by:
      stop in interface MatsConfig.StartStoppable
      Parameters:
      gracefulShutdownMillis - number of milliseconds to let the stage processors wait after having asked for them to shut down, and interrupting them if they have not shut down yet.
      Returns:
      whether it was successfully stopped (i.e. true if successfully stopped all listening threads).
    • remove

      boolean remove(int gracefulShutdownMillis)
      Should most probably only be used for testing!

      First invokes stop(gracefulShutdownMillis), and if successful removes the endpoint from its MatsFactory. This enables a new endpoint to be registered with the same endpointId as the one removed (which otherwise is not accepted). This might be of interest in testing scenarios, where you want to change the implementation of an endpoint from one test to another. There is currently no known situation where this makes sense to do "in production": Once the system is set up with the correct endpoints, it should most probably stay that way!

      Returns:
      whether the stop(int gracefulShutdownMillis) was successful, and thus whether the endpoint was removed from its MatsFactory.