--
>>>>>>>>>> Read the docs: http://akka.io/docs/
>>>>>>>>>> Check the FAQ: http://doc.akka.io/docs/akka/current/additional/faq.html
>>>>>>>>>> Search the archives: https://groups.google.com/group/akka-user
---
You received this message because you are subscribed to the Google Groups "Akka User List" group.
To unsubscribe from this group and stop receiving emails from it, send an email to akka-user+...@googlegroups.com.
To post to this group, send email to akka...@googlegroups.com.
Visit this group at http://groups.google.com/group/akka-user.
For more options, visit https://groups.google.com/d/optout.
Hi Simon,
tcpFlow is the description of a TCP connetion, it does not connect itself. Whenever you materialize that flow as part of a larger stream, it connects.
Your send() method calls "runFold" on a stream that contains this tcpFlow, therefore you always open a new connection in send().
You received this message because you are subscribed to a topic in the Google Groups "Akka User List" group.
To unsubscribe from this topic, visit https://groups.google.com/d/topic/akka-user/qpqWePkADwU/unsubscribe.
To unsubscribe from this group and all its topics, send an email to akka-user+...@googlegroups.com.
Hi Simon,
I think there are two conceptual difficulties you need to tackle:
The first is the problem which you describe with infinite / finite streams which is actually more one of the "traditional" (= actor based) push-style asynchronous programming versus the "new" [*] pull-style of reactive/akka streams which was introduced to deal with backpressure. The issue with backpressure is that it only works if all components take part in it. If you have one component that opts-out of backpressure it will have to fail or drop elements if it becomes overloaded and this component will become the weakest link (or the "Sollbruchstelle") of your application under load. Akka currently supports `Source.actorRef` (and `Sink.actorRef` respectively) which does exactly this translation from a push-style Actor API to the pull-style streams API. You usually don't want to use them as they will be limited by design and bound to fail under load.
Pull-style means that you need to write your program so that it is completely passive and waits for demand (you could also call that style "reactive", you setup your program to passively wait for a source to provide elements and then react to them). Writing "passive" programs is perfectly suited to services that follow the request / response principle. You setup your handler as a flow and just put it between the Source[Request] / Sink[Response].
But what does it mean for a client program which usually actively tries to achieve something? I think you can also build such a program in a passive style: if it doesn't take any dynamic input it is easy as you can create all the sources and sinks from static data. If it does take dynamic input (like user input), you just need a Source of that user input that only prompts the user for more input if there's demand. It should be possible to structure a program like this but it will be a pervasive change that cannot be recommended in all cases.
So, in reality for client applications you will probably use things like the brittle `Source.actorRef` and just statically configure the size of the buffers and queues to be big enough for the common use cases. (You could say that `Source.actorRef` is not more brittle than the JVM itself which you also need to configure with a maximum heap size.) In any case using streams will force you to think about these kind of issues.
This became quite a long answer but it also covers a lot of stuff :)
HTH
Johannes
[*] Of course, there's not too much conceptually new here. E.g. UNIX shell pipes and filters are very similar to the whole reactive streams concept (but constrained to byte streams): you have a buffer that can be asynchronously written to from one side and read from on the other side. The reader must poll if no data is currently available while the writer must poll while the buffer is full. Demand is signalled over the capacity of the shared buffer. Similar for TCP where demand is exchanged by notifying the peer of the capacity of the receive buffer. Etc.
There is another thing that just came up: Can I receive data on the client with a above approach when there was no prior request?
I made a small code example: