Ask vs Tell or forward for Actors using Akka Streams












1















Hi I am working with akka streams along with akka-stream-kafka. I am setting up a Stream with the below setup:



Source (Kafka) --> | Akka Actor Flow | --> Sink (MongoDB)


Actor Flow basically by Actors that will process data, below is the hierarchy:



                                      System
|
Master Actor
/
URLTypeHandler SerializedTypeHandler
/ |
Type1Handler Type2Handler SomeOtherHandler


So Kafka has the message, I write up the consumer and run it in atMostOnceSource configuration and use



Consumer.Control control =
Consumer.atMostOnceSource(consumerSettings, Subscriptions.topics(TOPIC))
.mapAsyncUnordered(10, record -> processAccessLog(rootHandler, record.value()))
.to(Sink.foreach(it -> System.out.println("FinalReturnedString--> " + it)))
.run(materializer);


I've used a print as a sink initially, just to get the flow running.



and the processAccessLog is defined as:



private static CompletionStage<String> processAccessLog(ActorRef handler, byte value) {

handler.tell(value, ActorRef.noSender());

return CompletableFuture.completedFuture("");
}


Now, from the definition ask must be used when an actor is expecting a response, makes sense in this case since I want to return values to be written in the sink.



But everyone (including docs), mention to avoid ask and rather use tell and forward, an amazing blog is written on it Don't Ask, Tell.



In the blog he mentions, in case of nested actors, use tell for the first message and then use forward for the message to reach the destination and then after processing directly send the message back to the root actor.



from the blog



Now here is the problem,




  1. How do I send the message from D back to A, such that I can still use the sink.

  2. Is it good practice to have open ended streams? e.g. Streams where Sink doesn't matter because the actors have already done the job. (I don't think it is recommend to do so, seems flawed).










share|improve this question





























    1















    Hi I am working with akka streams along with akka-stream-kafka. I am setting up a Stream with the below setup:



    Source (Kafka) --> | Akka Actor Flow | --> Sink (MongoDB)


    Actor Flow basically by Actors that will process data, below is the hierarchy:



                                          System
    |
    Master Actor
    /
    URLTypeHandler SerializedTypeHandler
    / |
    Type1Handler Type2Handler SomeOtherHandler


    So Kafka has the message, I write up the consumer and run it in atMostOnceSource configuration and use



    Consumer.Control control =
    Consumer.atMostOnceSource(consumerSettings, Subscriptions.topics(TOPIC))
    .mapAsyncUnordered(10, record -> processAccessLog(rootHandler, record.value()))
    .to(Sink.foreach(it -> System.out.println("FinalReturnedString--> " + it)))
    .run(materializer);


    I've used a print as a sink initially, just to get the flow running.



    and the processAccessLog is defined as:



    private static CompletionStage<String> processAccessLog(ActorRef handler, byte value) {

    handler.tell(value, ActorRef.noSender());

    return CompletableFuture.completedFuture("");
    }


    Now, from the definition ask must be used when an actor is expecting a response, makes sense in this case since I want to return values to be written in the sink.



    But everyone (including docs), mention to avoid ask and rather use tell and forward, an amazing blog is written on it Don't Ask, Tell.



    In the blog he mentions, in case of nested actors, use tell for the first message and then use forward for the message to reach the destination and then after processing directly send the message back to the root actor.



    from the blog



    Now here is the problem,




    1. How do I send the message from D back to A, such that I can still use the sink.

    2. Is it good practice to have open ended streams? e.g. Streams where Sink doesn't matter because the actors have already done the job. (I don't think it is recommend to do so, seems flawed).










    share|improve this question



























      1












      1








      1








      Hi I am working with akka streams along with akka-stream-kafka. I am setting up a Stream with the below setup:



      Source (Kafka) --> | Akka Actor Flow | --> Sink (MongoDB)


      Actor Flow basically by Actors that will process data, below is the hierarchy:



                                            System
      |
      Master Actor
      /
      URLTypeHandler SerializedTypeHandler
      / |
      Type1Handler Type2Handler SomeOtherHandler


      So Kafka has the message, I write up the consumer and run it in atMostOnceSource configuration and use



      Consumer.Control control =
      Consumer.atMostOnceSource(consumerSettings, Subscriptions.topics(TOPIC))
      .mapAsyncUnordered(10, record -> processAccessLog(rootHandler, record.value()))
      .to(Sink.foreach(it -> System.out.println("FinalReturnedString--> " + it)))
      .run(materializer);


      I've used a print as a sink initially, just to get the flow running.



      and the processAccessLog is defined as:



      private static CompletionStage<String> processAccessLog(ActorRef handler, byte value) {

      handler.tell(value, ActorRef.noSender());

      return CompletableFuture.completedFuture("");
      }


      Now, from the definition ask must be used when an actor is expecting a response, makes sense in this case since I want to return values to be written in the sink.



      But everyone (including docs), mention to avoid ask and rather use tell and forward, an amazing blog is written on it Don't Ask, Tell.



      In the blog he mentions, in case of nested actors, use tell for the first message and then use forward for the message to reach the destination and then after processing directly send the message back to the root actor.



      from the blog



      Now here is the problem,




      1. How do I send the message from D back to A, such that I can still use the sink.

      2. Is it good practice to have open ended streams? e.g. Streams where Sink doesn't matter because the actors have already done the job. (I don't think it is recommend to do so, seems flawed).










      share|improve this question
















      Hi I am working with akka streams along with akka-stream-kafka. I am setting up a Stream with the below setup:



      Source (Kafka) --> | Akka Actor Flow | --> Sink (MongoDB)


      Actor Flow basically by Actors that will process data, below is the hierarchy:



                                            System
      |
      Master Actor
      /
      URLTypeHandler SerializedTypeHandler
      / |
      Type1Handler Type2Handler SomeOtherHandler


      So Kafka has the message, I write up the consumer and run it in atMostOnceSource configuration and use



      Consumer.Control control =
      Consumer.atMostOnceSource(consumerSettings, Subscriptions.topics(TOPIC))
      .mapAsyncUnordered(10, record -> processAccessLog(rootHandler, record.value()))
      .to(Sink.foreach(it -> System.out.println("FinalReturnedString--> " + it)))
      .run(materializer);


      I've used a print as a sink initially, just to get the flow running.



      and the processAccessLog is defined as:



      private static CompletionStage<String> processAccessLog(ActorRef handler, byte value) {

      handler.tell(value, ActorRef.noSender());

      return CompletableFuture.completedFuture("");
      }


      Now, from the definition ask must be used when an actor is expecting a response, makes sense in this case since I want to return values to be written in the sink.



      But everyone (including docs), mention to avoid ask and rather use tell and forward, an amazing blog is written on it Don't Ask, Tell.



      In the blog he mentions, in case of nested actors, use tell for the first message and then use forward for the message to reach the destination and then after processing directly send the message back to the root actor.



      from the blog



      Now here is the problem,




      1. How do I send the message from D back to A, such that I can still use the sink.

      2. Is it good practice to have open ended streams? e.g. Streams where Sink doesn't matter because the actors have already done the job. (I don't think it is recommend to do so, seems flawed).







      java akka akka-stream






      share|improve this question















      share|improve this question













      share|improve this question




      share|improve this question








      edited Nov 19 '18 at 12:55









      Ramon J Romero y Vigil

      12.1k24273




      12.1k24273










      asked Nov 16 '18 at 7:38









      iam.Carrotiam.Carrot

      2,36121140




      2,36121140
























          2 Answers
          2






          active

          oldest

          votes


















          1














          ask is Still the Right Pattern



          From the linked blog article, one "drawback" of ask is:




          blocking an actor itself, which cannot pick any new messages until the
          response arrives and processing finishes.




          However, in akka-stream this is the exact feature we are looking for, a.k.a. "back-pressure". If the Flow or Sink are taking a long time to process data then we want the Source to slow down.



          As a side note, I think the claim in the blog post that the additional listener Actor results in an implementation that is "dozens times heavier" is an exaggeration. Obviously an intermediate Actor adds some latency overhead but not 12x more.



          Elimination of Back-Pressure



          Any implementation of what you are looking for would effectively eliminate back-pressure. An intermediate Flow that only used tell would continuously propagate demand back to the Source regardless of whether or not your processing logic, within the handler Actors, was completing its calculations at the same speed that the Source is generating data.
          Consider an extreme example: what if your Source could produce 1 million messages per second but the Actor receiving those messages via tell could only process 1 message per second. What would happen to that Actor's mailbox?



          By using the ask pattern in an intermediate Flow you are purposefully linking the speed of the handlers and the speed with which your Source produces data.



          If you are willing to remove back-pressure signaling, from the Sink to the Source, then you might as well not use akka-stream in the first place. You can have either back-pressure or non-blocking messaging, but not both.






          share|improve this answer


























          • Thanks for the great explanation, what I ended up doing was I processed my stream using .mapAsyncUnordered(10, record -> ask(ActorA, record.value(), followed with forward from ActorA -> ActorB -> ActorC and ActorC replies to stream using getSender().tell(myResponse, ActorRef.noSender());.And then leverage Sink for all outward data store That should still propagate back pressure right? (as per my understanding)

            – iam.Carrot
            Nov 20 '18 at 19:11













          • @iam.Carrot You are welcome. As long as there is an ask involved then yes, back pressure is propagated.

            – Ramon J Romero y Vigil
            Nov 20 '18 at 20:51











          • perfect thanks much

            – iam.Carrot
            Nov 21 '18 at 4:33











          • just a quick thing, is it relevant to perform a ActorRef.ask() at Sink as well if you have a whole actor system to handle Sink? or would it provide backpressure even if we have tell

            – iam.Carrot
            Nov 23 '18 at 8:49



















          1














          Ramon J Romero y Vigil is right but I will try to extend the response.



          1) I think that the "Don't ask, tell" dogma is mostly for Actor systems architecture. Here you need to return a Future so the stream can resolve the processed result, you have two options:




          • Use ask

          • Create an actor per event and pass them Promise so a Future will be complete when this actor receives the data (you can use the getSender method so D can send the response to A). There is no way to send a Promise or Future in a message (The are not Serialisable) so the creation of this short living actors can not be avoided.


          At the end you are doing mostly the same...



          2) It's perfectly fine to use an empty Sink to finalise the stream (indeed akka provides the Sink.ignore() method to do so).



          Seems like you are missing the reason why you are using streams, they are cool abstraction to provide composability, concurrency and back pressure. In the other hand, actors can not be compose and is hard to handle back pressure. If you don't need this features and your actors can have the work done easily you shouldn't use akka-streams in first place.






          share|improve this answer
























          • great thanks for the answer, especially on the second point since I was worried about it. + 1

            – iam.Carrot
            Nov 20 '18 at 19:13











          Your Answer






          StackExchange.ifUsing("editor", function () {
          StackExchange.using("externalEditor", function () {
          StackExchange.using("snippets", function () {
          StackExchange.snippets.init();
          });
          });
          }, "code-snippets");

          StackExchange.ready(function() {
          var channelOptions = {
          tags: "".split(" "),
          id: "1"
          };
          initTagRenderer("".split(" "), "".split(" "), channelOptions);

          StackExchange.using("externalEditor", function() {
          // Have to fire editor after snippets, if snippets enabled
          if (StackExchange.settings.snippets.snippetsEnabled) {
          StackExchange.using("snippets", function() {
          createEditor();
          });
          }
          else {
          createEditor();
          }
          });

          function createEditor() {
          StackExchange.prepareEditor({
          heartbeatType: 'answer',
          autoActivateHeartbeat: false,
          convertImagesToLinks: true,
          noModals: true,
          showLowRepImageUploadWarning: true,
          reputationToPostImages: 10,
          bindNavPrevention: true,
          postfix: "",
          imageUploader: {
          brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
          contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
          allowUrls: true
          },
          onDemand: true,
          discardSelector: ".discard-answer"
          ,immediatelyShowMarkdownHelp:true
          });


          }
          });














          draft saved

          draft discarded


















          StackExchange.ready(
          function () {
          StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53333374%2fask-vs-tell-or-forward-for-actors-using-akka-streams%23new-answer', 'question_page');
          }
          );

          Post as a guest















          Required, but never shown

























          2 Answers
          2






          active

          oldest

          votes








          2 Answers
          2






          active

          oldest

          votes









          active

          oldest

          votes






          active

          oldest

          votes









          1














          ask is Still the Right Pattern



          From the linked blog article, one "drawback" of ask is:




          blocking an actor itself, which cannot pick any new messages until the
          response arrives and processing finishes.




          However, in akka-stream this is the exact feature we are looking for, a.k.a. "back-pressure". If the Flow or Sink are taking a long time to process data then we want the Source to slow down.



          As a side note, I think the claim in the blog post that the additional listener Actor results in an implementation that is "dozens times heavier" is an exaggeration. Obviously an intermediate Actor adds some latency overhead but not 12x more.



          Elimination of Back-Pressure



          Any implementation of what you are looking for would effectively eliminate back-pressure. An intermediate Flow that only used tell would continuously propagate demand back to the Source regardless of whether or not your processing logic, within the handler Actors, was completing its calculations at the same speed that the Source is generating data.
          Consider an extreme example: what if your Source could produce 1 million messages per second but the Actor receiving those messages via tell could only process 1 message per second. What would happen to that Actor's mailbox?



          By using the ask pattern in an intermediate Flow you are purposefully linking the speed of the handlers and the speed with which your Source produces data.



          If you are willing to remove back-pressure signaling, from the Sink to the Source, then you might as well not use akka-stream in the first place. You can have either back-pressure or non-blocking messaging, but not both.






          share|improve this answer


























          • Thanks for the great explanation, what I ended up doing was I processed my stream using .mapAsyncUnordered(10, record -> ask(ActorA, record.value(), followed with forward from ActorA -> ActorB -> ActorC and ActorC replies to stream using getSender().tell(myResponse, ActorRef.noSender());.And then leverage Sink for all outward data store That should still propagate back pressure right? (as per my understanding)

            – iam.Carrot
            Nov 20 '18 at 19:11













          • @iam.Carrot You are welcome. As long as there is an ask involved then yes, back pressure is propagated.

            – Ramon J Romero y Vigil
            Nov 20 '18 at 20:51











          • perfect thanks much

            – iam.Carrot
            Nov 21 '18 at 4:33











          • just a quick thing, is it relevant to perform a ActorRef.ask() at Sink as well if you have a whole actor system to handle Sink? or would it provide backpressure even if we have tell

            – iam.Carrot
            Nov 23 '18 at 8:49
















          1














          ask is Still the Right Pattern



          From the linked blog article, one "drawback" of ask is:




          blocking an actor itself, which cannot pick any new messages until the
          response arrives and processing finishes.




          However, in akka-stream this is the exact feature we are looking for, a.k.a. "back-pressure". If the Flow or Sink are taking a long time to process data then we want the Source to slow down.



          As a side note, I think the claim in the blog post that the additional listener Actor results in an implementation that is "dozens times heavier" is an exaggeration. Obviously an intermediate Actor adds some latency overhead but not 12x more.



          Elimination of Back-Pressure



          Any implementation of what you are looking for would effectively eliminate back-pressure. An intermediate Flow that only used tell would continuously propagate demand back to the Source regardless of whether or not your processing logic, within the handler Actors, was completing its calculations at the same speed that the Source is generating data.
          Consider an extreme example: what if your Source could produce 1 million messages per second but the Actor receiving those messages via tell could only process 1 message per second. What would happen to that Actor's mailbox?



          By using the ask pattern in an intermediate Flow you are purposefully linking the speed of the handlers and the speed with which your Source produces data.



          If you are willing to remove back-pressure signaling, from the Sink to the Source, then you might as well not use akka-stream in the first place. You can have either back-pressure or non-blocking messaging, but not both.






          share|improve this answer


























          • Thanks for the great explanation, what I ended up doing was I processed my stream using .mapAsyncUnordered(10, record -> ask(ActorA, record.value(), followed with forward from ActorA -> ActorB -> ActorC and ActorC replies to stream using getSender().tell(myResponse, ActorRef.noSender());.And then leverage Sink for all outward data store That should still propagate back pressure right? (as per my understanding)

            – iam.Carrot
            Nov 20 '18 at 19:11













          • @iam.Carrot You are welcome. As long as there is an ask involved then yes, back pressure is propagated.

            – Ramon J Romero y Vigil
            Nov 20 '18 at 20:51











          • perfect thanks much

            – iam.Carrot
            Nov 21 '18 at 4:33











          • just a quick thing, is it relevant to perform a ActorRef.ask() at Sink as well if you have a whole actor system to handle Sink? or would it provide backpressure even if we have tell

            – iam.Carrot
            Nov 23 '18 at 8:49














          1












          1








          1







          ask is Still the Right Pattern



          From the linked blog article, one "drawback" of ask is:




          blocking an actor itself, which cannot pick any new messages until the
          response arrives and processing finishes.




          However, in akka-stream this is the exact feature we are looking for, a.k.a. "back-pressure". If the Flow or Sink are taking a long time to process data then we want the Source to slow down.



          As a side note, I think the claim in the blog post that the additional listener Actor results in an implementation that is "dozens times heavier" is an exaggeration. Obviously an intermediate Actor adds some latency overhead but not 12x more.



          Elimination of Back-Pressure



          Any implementation of what you are looking for would effectively eliminate back-pressure. An intermediate Flow that only used tell would continuously propagate demand back to the Source regardless of whether or not your processing logic, within the handler Actors, was completing its calculations at the same speed that the Source is generating data.
          Consider an extreme example: what if your Source could produce 1 million messages per second but the Actor receiving those messages via tell could only process 1 message per second. What would happen to that Actor's mailbox?



          By using the ask pattern in an intermediate Flow you are purposefully linking the speed of the handlers and the speed with which your Source produces data.



          If you are willing to remove back-pressure signaling, from the Sink to the Source, then you might as well not use akka-stream in the first place. You can have either back-pressure or non-blocking messaging, but not both.






          share|improve this answer















          ask is Still the Right Pattern



          From the linked blog article, one "drawback" of ask is:




          blocking an actor itself, which cannot pick any new messages until the
          response arrives and processing finishes.




          However, in akka-stream this is the exact feature we are looking for, a.k.a. "back-pressure". If the Flow or Sink are taking a long time to process data then we want the Source to slow down.



          As a side note, I think the claim in the blog post that the additional listener Actor results in an implementation that is "dozens times heavier" is an exaggeration. Obviously an intermediate Actor adds some latency overhead but not 12x more.



          Elimination of Back-Pressure



          Any implementation of what you are looking for would effectively eliminate back-pressure. An intermediate Flow that only used tell would continuously propagate demand back to the Source regardless of whether or not your processing logic, within the handler Actors, was completing its calculations at the same speed that the Source is generating data.
          Consider an extreme example: what if your Source could produce 1 million messages per second but the Actor receiving those messages via tell could only process 1 message per second. What would happen to that Actor's mailbox?



          By using the ask pattern in an intermediate Flow you are purposefully linking the speed of the handlers and the speed with which your Source produces data.



          If you are willing to remove back-pressure signaling, from the Sink to the Source, then you might as well not use akka-stream in the first place. You can have either back-pressure or non-blocking messaging, but not both.







          share|improve this answer














          share|improve this answer



          share|improve this answer








          edited Nov 19 '18 at 14:10

























          answered Nov 19 '18 at 12:51









          Ramon J Romero y VigilRamon J Romero y Vigil

          12.1k24273




          12.1k24273













          • Thanks for the great explanation, what I ended up doing was I processed my stream using .mapAsyncUnordered(10, record -> ask(ActorA, record.value(), followed with forward from ActorA -> ActorB -> ActorC and ActorC replies to stream using getSender().tell(myResponse, ActorRef.noSender());.And then leverage Sink for all outward data store That should still propagate back pressure right? (as per my understanding)

            – iam.Carrot
            Nov 20 '18 at 19:11













          • @iam.Carrot You are welcome. As long as there is an ask involved then yes, back pressure is propagated.

            – Ramon J Romero y Vigil
            Nov 20 '18 at 20:51











          • perfect thanks much

            – iam.Carrot
            Nov 21 '18 at 4:33











          • just a quick thing, is it relevant to perform a ActorRef.ask() at Sink as well if you have a whole actor system to handle Sink? or would it provide backpressure even if we have tell

            – iam.Carrot
            Nov 23 '18 at 8:49



















          • Thanks for the great explanation, what I ended up doing was I processed my stream using .mapAsyncUnordered(10, record -> ask(ActorA, record.value(), followed with forward from ActorA -> ActorB -> ActorC and ActorC replies to stream using getSender().tell(myResponse, ActorRef.noSender());.And then leverage Sink for all outward data store That should still propagate back pressure right? (as per my understanding)

            – iam.Carrot
            Nov 20 '18 at 19:11













          • @iam.Carrot You are welcome. As long as there is an ask involved then yes, back pressure is propagated.

            – Ramon J Romero y Vigil
            Nov 20 '18 at 20:51











          • perfect thanks much

            – iam.Carrot
            Nov 21 '18 at 4:33











          • just a quick thing, is it relevant to perform a ActorRef.ask() at Sink as well if you have a whole actor system to handle Sink? or would it provide backpressure even if we have tell

            – iam.Carrot
            Nov 23 '18 at 8:49

















          Thanks for the great explanation, what I ended up doing was I processed my stream using .mapAsyncUnordered(10, record -> ask(ActorA, record.value(), followed with forward from ActorA -> ActorB -> ActorC and ActorC replies to stream using getSender().tell(myResponse, ActorRef.noSender());.And then leverage Sink for all outward data store That should still propagate back pressure right? (as per my understanding)

          – iam.Carrot
          Nov 20 '18 at 19:11







          Thanks for the great explanation, what I ended up doing was I processed my stream using .mapAsyncUnordered(10, record -> ask(ActorA, record.value(), followed with forward from ActorA -> ActorB -> ActorC and ActorC replies to stream using getSender().tell(myResponse, ActorRef.noSender());.And then leverage Sink for all outward data store That should still propagate back pressure right? (as per my understanding)

          – iam.Carrot
          Nov 20 '18 at 19:11















          @iam.Carrot You are welcome. As long as there is an ask involved then yes, back pressure is propagated.

          – Ramon J Romero y Vigil
          Nov 20 '18 at 20:51





          @iam.Carrot You are welcome. As long as there is an ask involved then yes, back pressure is propagated.

          – Ramon J Romero y Vigil
          Nov 20 '18 at 20:51













          perfect thanks much

          – iam.Carrot
          Nov 21 '18 at 4:33





          perfect thanks much

          – iam.Carrot
          Nov 21 '18 at 4:33













          just a quick thing, is it relevant to perform a ActorRef.ask() at Sink as well if you have a whole actor system to handle Sink? or would it provide backpressure even if we have tell

          – iam.Carrot
          Nov 23 '18 at 8:49





          just a quick thing, is it relevant to perform a ActorRef.ask() at Sink as well if you have a whole actor system to handle Sink? or would it provide backpressure even if we have tell

          – iam.Carrot
          Nov 23 '18 at 8:49













          1














          Ramon J Romero y Vigil is right but I will try to extend the response.



          1) I think that the "Don't ask, tell" dogma is mostly for Actor systems architecture. Here you need to return a Future so the stream can resolve the processed result, you have two options:




          • Use ask

          • Create an actor per event and pass them Promise so a Future will be complete when this actor receives the data (you can use the getSender method so D can send the response to A). There is no way to send a Promise or Future in a message (The are not Serialisable) so the creation of this short living actors can not be avoided.


          At the end you are doing mostly the same...



          2) It's perfectly fine to use an empty Sink to finalise the stream (indeed akka provides the Sink.ignore() method to do so).



          Seems like you are missing the reason why you are using streams, they are cool abstraction to provide composability, concurrency and back pressure. In the other hand, actors can not be compose and is hard to handle back pressure. If you don't need this features and your actors can have the work done easily you shouldn't use akka-streams in first place.






          share|improve this answer
























          • great thanks for the answer, especially on the second point since I was worried about it. + 1

            – iam.Carrot
            Nov 20 '18 at 19:13
















          1














          Ramon J Romero y Vigil is right but I will try to extend the response.



          1) I think that the "Don't ask, tell" dogma is mostly for Actor systems architecture. Here you need to return a Future so the stream can resolve the processed result, you have two options:




          • Use ask

          • Create an actor per event and pass them Promise so a Future will be complete when this actor receives the data (you can use the getSender method so D can send the response to A). There is no way to send a Promise or Future in a message (The are not Serialisable) so the creation of this short living actors can not be avoided.


          At the end you are doing mostly the same...



          2) It's perfectly fine to use an empty Sink to finalise the stream (indeed akka provides the Sink.ignore() method to do so).



          Seems like you are missing the reason why you are using streams, they are cool abstraction to provide composability, concurrency and back pressure. In the other hand, actors can not be compose and is hard to handle back pressure. If you don't need this features and your actors can have the work done easily you shouldn't use akka-streams in first place.






          share|improve this answer
























          • great thanks for the answer, especially on the second point since I was worried about it. + 1

            – iam.Carrot
            Nov 20 '18 at 19:13














          1












          1








          1







          Ramon J Romero y Vigil is right but I will try to extend the response.



          1) I think that the "Don't ask, tell" dogma is mostly for Actor systems architecture. Here you need to return a Future so the stream can resolve the processed result, you have two options:




          • Use ask

          • Create an actor per event and pass them Promise so a Future will be complete when this actor receives the data (you can use the getSender method so D can send the response to A). There is no way to send a Promise or Future in a message (The are not Serialisable) so the creation of this short living actors can not be avoided.


          At the end you are doing mostly the same...



          2) It's perfectly fine to use an empty Sink to finalise the stream (indeed akka provides the Sink.ignore() method to do so).



          Seems like you are missing the reason why you are using streams, they are cool abstraction to provide composability, concurrency and back pressure. In the other hand, actors can not be compose and is hard to handle back pressure. If you don't need this features and your actors can have the work done easily you shouldn't use akka-streams in first place.






          share|improve this answer













          Ramon J Romero y Vigil is right but I will try to extend the response.



          1) I think that the "Don't ask, tell" dogma is mostly for Actor systems architecture. Here you need to return a Future so the stream can resolve the processed result, you have two options:




          • Use ask

          • Create an actor per event and pass them Promise so a Future will be complete when this actor receives the data (you can use the getSender method so D can send the response to A). There is no way to send a Promise or Future in a message (The are not Serialisable) so the creation of this short living actors can not be avoided.


          At the end you are doing mostly the same...



          2) It's perfectly fine to use an empty Sink to finalise the stream (indeed akka provides the Sink.ignore() method to do so).



          Seems like you are missing the reason why you are using streams, they are cool abstraction to provide composability, concurrency and back pressure. In the other hand, actors can not be compose and is hard to handle back pressure. If you don't need this features and your actors can have the work done easily you shouldn't use akka-streams in first place.







          share|improve this answer












          share|improve this answer



          share|improve this answer










          answered Nov 20 '18 at 10:34









          RoberMPRoberMP

          796616




          796616













          • great thanks for the answer, especially on the second point since I was worried about it. + 1

            – iam.Carrot
            Nov 20 '18 at 19:13



















          • great thanks for the answer, especially on the second point since I was worried about it. + 1

            – iam.Carrot
            Nov 20 '18 at 19:13

















          great thanks for the answer, especially on the second point since I was worried about it. + 1

          – iam.Carrot
          Nov 20 '18 at 19:13





          great thanks for the answer, especially on the second point since I was worried about it. + 1

          – iam.Carrot
          Nov 20 '18 at 19:13


















          draft saved

          draft discarded




















































          Thanks for contributing an answer to Stack Overflow!


          • Please be sure to answer the question. Provide details and share your research!

          But avoid



          • Asking for help, clarification, or responding to other answers.

          • Making statements based on opinion; back them up with references or personal experience.


          To learn more, see our tips on writing great answers.




          draft saved


          draft discarded














          StackExchange.ready(
          function () {
          StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53333374%2fask-vs-tell-or-forward-for-actors-using-akka-streams%23new-answer', 'question_page');
          }
          );

          Post as a guest















          Required, but never shown





















































          Required, but never shown














          Required, but never shown












          Required, but never shown







          Required, but never shown

































          Required, but never shown














          Required, but never shown












          Required, but never shown







          Required, but never shown







          Popular posts from this blog

          List item for chat from Array inside array React Native

          Thiostrepton

          Caerphilly