My application has an API using SprayCan. In the application, any blocking code has a separate dispatcher for each specific resource.
Is it necessary to protect the API service from being blocked by the application by configuring it with it's own Dispatcher too?
Also is it common practice to use a Router for an API service to handle a larger capacity of requests?
class MyService extends Actor with HttpService {...}
val service = system.actorOf(MyService.props(...).withDispatcher(???))
Is it necessary to protect the API service from being blocked by the
application by configuring it with it's own Dispatcher too?
Usually not necessary. Check reference.conf that comes as default config with Spray to see if that dispatcher will satisfy your needs. If not, provide a custom one.
Also is it common practice to use a Router for an API service to
handle a larger capacity of requests?
Usually requests are handed off to another Actor to unblock the route or ran as Future (possibly on a separate thread pool). See all available options here: How does spray.routing.HttpService dispatch requests?.
Finally, you should not block in the route handler because it will block your service. From your description it sounds like your blocking code runs in a Future or similar. As long as it does not make route handler wait for result/block it's fine.
Related
I am using vert.x as an api gateway to route calls to downstream services.
As of now, I am using single web client instance which is shared across multiple verticles (injected through guice)
Does it make sense for each verticle to have it's own webclient? Will it help in boosting performance? (My each gateway instance runs 64 vericles and handles approximately 1000 requests per second)
What are the pros and cons of each approach?
Can someone help to figure out what's the ideal strategy for the same?
Thanks
Vert.x is optimized for using a single WebClient per-Verticle. Sharing a single WebClient instance between threads might work, but it can negatively affect performance, and could lead to some code running on the "wrong" event-loop thread, as described by Julien Viet, the lead developer of Vert.x:
So if you share a web client between verticles, then your verticle
might reuse a connection previously open (because of pooling) and you
will get callbacks on the event loop you won't expect. In addition
there is synchronization in the web client that might become contented
when used intensively from different threads.
Additionally, the Vert.x documentation for HttpClient, which is the underlying object used by WebClient, explicitly states not to share it between Vert.x Contexts (each Verticle gets its own Context):
The HttpClient can be used in a Verticle or embedded.
When used in a Verticle, the Verticle should use its own client
instance.
More generally a client should not be shared between different Vert.x
contexts as it can lead to unexpected behavior.
For example a keep-alive connection will call the client handlers on
the context of the request that opened the connection, subsequent
requests will use the same context.
As I understand, Dynatrace does not support Service Fabric Actors.
Is there an extensibility mechanism where I could add myself? For example, can I plug myself before and after every ActorProxy call, and/or before and after every method call on an Actor?
You can build a customized ActorProxy to add logging on the caller side.
Next, you can add some code into the Actor to add logging on the Actor side. Use OnPreActorMethodAsync and OnPostActorMethodAsync and some reflection to get context.
I have a service exposing a REST endpoint that, after a couple of transformations, calls a third-party service also via its REST endpoint.
I would like to implement some sort of throttling on my service to avoid being throttled by this third-party service. Note that my service's endpoint accepts only one request and not a list of them. I'm using Play and we also have Akka Streams as dependency.
My first though was to have my service saving the requests into a database table and then have an Akka Streams Source, leveraging the throttle function, picking tasks, applying the transformations and then calling the external service.
Is this a reasanoble approach or does it have any severe drawbacks?
Thanks!
Why save the requests to the database? Does the queue need to survive restarts and/or do you run a load-balanced setup that needs to somehow synchronize the requests?
If you don't need the above I'd think using only Source.queue to store the task data would work just as well?
And maybe you already thought of this: If you want to make your endpoint more resilient you should allow your API to send a 'sorry, busy' response and drop the request instead of queuing it if your queue grows beyond a certain size.
I have an application utilizing Spray, Akka, and Scala. The current unit testing is done via Scala Test. The application uses Spray routing to determine and parse some rudimentary data on web requests then passes it to an actor to do the required actions. For Spray we use a custom initialization class that inherits from spray.servlet.Initializer which configures and starts each of the actors. Part of those actions are to call out to some 7 or 8 other web services. Each has an actor to handle the communications with their respective services. So, we do a bunch of logic in the main actor which delegates the communication to other actors and at the end it processes all of the returned data in addition to it's own work along the way.
I would like to test the system as a whole using Scala Test and Akka Testkit using Testkit to substitute the communication actors to return suitable test data.
The question is two part.
What is the better approach to testing? I could use Scala Testkit to make requests through the Spray routing service via Spray Testkit. The alternative is, since the main actor takes the routing service results via a case class, is to just to directly pass the message to that actor skipping the routing service. Both have their merits. I however do find the documentation scant on Spray testkit. How would one sub the actors via Akka Testkit when there is initialization logic for those actors in spray.servlet.Initializer?
The second is how does one set up a more complex actor system via Akka Testkit. The documentation mentions this is possible but is far from expressive on exactly how one would do that. I have the routing service which is an actor that talks to another actor that is the bulk of business logic but then talks to several other actors. Are these communication actors considered "Child" actors in reference to the Akka Testkit documentation? Is there a project that demonstrates best practices in testing a rich Akka actor system as a whole?
My instincts in this case are to have a Spray Testkit based set of tests to test our routing system. Then, have a set of tests that send our data case class to the master actor with mocked comm actors behind it and verify we get the correct response back from the master actor.
I usually create tests for each layer of my application. Also, i mock the other layer when i'm testing the current layer. If i'm testing business i would mock the DAOs, if i'm testing spray routes i mock the business object(that is used by my spray routes).
I always try to start creating tests before the main program when i'm working with Actors and Spray, it helps in how should be my application architecture. Many times i need to refactor my class to use dependency injection or do not set the val in the current class/trait, so i can mock the vals.
I am trying to use Akka to implement the following (I think I'm trying to use Akka the proper way):
I have a system where I have n resource listeners. Essentially a resource listener is an entity that will listen on an input resource and publish what it sees (i.e. polling a database, tailing a log file, etc.).
So I want to use Akka actors to do these little bits of work units (listening on a resource). I've noticed that the Akka gives me a thread pool of t threads which may be less than the number of listeners. Unfortunately for me, getting a message from these resource listeners might be blocking, so it could take seconds, minutes, before the next message pops up.
Is there any way to suspend a resource listener so it leaves the thread to another actor and we'll come back to it a little later in time?
Executive Summary
What you want is for your producer API (the resources) to be asynchronous, or at least support non-blocking operations (so that you can do polling). If the API does not support that, then there is no way to retrofit this property, not even using the almighty actors ;-)
Strategies for Different Situations
Only Blocking API
If the resources only support the blocking getWhatever() method of retrieving things, then you must allocate one thread per resource. An Actor with a PinnedDispatcher could be a way to do this. But be aware that the actor will not be responsive while waiting for events from the resource.
Non-Blocking but Synchronous API
If there is a peek() or poll() method on the resource API, you can use one actor per resource, have them share a thread (or pool) and schedule the polling as required (i.e. every 100ms or whatever you need). This has the huge advantage that nobody is actually blocked and the whole system remains responsive. But latency for event reception will be of the order of your schedule interval.
Proper Asynchronous API
If you have enough good karma to encounter a nice asynchronous API, then simply register a callback which will send a message to the actor whenever an event occurs. Sadly, this is not the norm.
PS:
The JVM does not support wrapping up the current call stack, doing something else and return to that same processing state later. A method can only be popped of the stack when it is actually finished.
In general, you should try to avoid blocking operations in actors. For file IO, there are asynchronous libraries and for some databases, too. If that is not an option for you, you can set change the default dispatcher so that the underlying thread pool expands as needed.
One option is to call your blocking APIs inside Futures. The Futures should use an ExecutionContext (thread pool) that is separate from the Actors' ExecutionContext.
See this blog post for an example (specifically CacheActor.findValueForSender).