Is there some kind of plugin for message queues li...
# ktor
d
Is there some kind of plugin for message queues like Kafka or RabbitMQ for Ktor? Also, is there some kind of integration w/ Prometheus monitoring?
d
Nothing specific to Ktor as far as I know
I guess that prometheus monitoring could have a plugin for the monitoring feature: https://ktor.io/advanced/events.html But what about message queues, do you have in mind any special integration with Ktor in addition to just using a library for it?
d
That events page looks good! Can I also record response timing with it? And what happens if a request hangs, does it have some kind of timeout system, and does it also go through these events?
For message queues, I'm really looking for a similar pattern to the event bus in Vert.x.. right now I have a bunch of internal http endpoints for inter-microservice communications... which is not always so reliable, and is hard to monitor...
d
Have you tried to use the event bus from vertex directly in ktor?
Or would require an AaplicationEngine leveraging vertex? As far as I remember vertex used Netty under the hood. Maybe you can configure only the event bus from vertex
d
To initialize it you need a Vertx instance along with its threadpool, etc.. it would have been nice to have some kind of integration, since I also use the Vert.x async db clients a lot... https://github.com/ktorio/ktor/issues/286
d
I see. Lets ping there to see if there are advances in that direction. I created a page to show how to create additional ApplicationEngines : https://ktor.io/advanced/engines.html
d
The Dropwizard Metrics aren't soo good for Prometheus (https://www.robustperception.io/exposing-dropwizard-metrics-to-prometheus/), but then I guess it's implemented over the
events
you pointed to earlier?
Is there a timeout for responses when something hangs (like a request that doesn't return a response, or some communication w/ an external microservice that's taking too much time)? And do those events cover this case? We've been having this issue in Vert.x services recently, and we're considering refactoring them to Ktor...
And these points are very important to make this decision...
d
let me check
https://github.com/ktorio/ktor/blob/master/ktor-features/ktor-metrics/src/io/ktor/metrics/Metrics.kt This is what you can expect from metrics. It uses dropwizard’s Metrics internally. What it does is intercept requests and pass time information to dropwizard’s. Nothing too complex. As far as I understand looking at that code, it doesn’t implement anything related to timeouts. Probably because if you are for example doing a http request that could hang, you can configure a timeout there. I think coroutines provide functionality to cancel contexts and hook cancelations and thus could be possible to implement timeouts, but you should hook them to your libraries. If you have feedback/examples/use cases related to this, would be an interesting feedback. Let me ask the status of timeouts in the application engine
I’m also asking if it is feasible implementing the circuit breaker pattern as a ktor feature. For example by automatically associating services to calls and then routes and making that feature to prevent performing calls using those services until the service has been restored.
👍🏼 1
d
Circuit breakers are also very important in Microservices simple smile... I think that any code running in a route could possibly have an option to give a global or route specific timeout (maybe with the
withTimeout
in coroutines?), if not already implemented that way. Right now we use Odoo for our ERP and it needs to send a request and receive an answer from a microservice (currently in Vert.x), our Prometheus histogram is showing that a lot of those requests are hanging... and the UI also hangs with them, so there isn't even proper feedback being returned to Odoo. In this case a timeout would at least make it possible to give an error message back to the UI (and odoo logs) that the connection was established (it might be the connection that didn't go through also... which could help pinpoint the issue), but that the service hung while handling the request.
👌 1
d
I think that with ktor’s metrics you can see how many requests have started per route and how many have finished, and information about times per call
I’m trying to do a prototype for a circuitbreaker
d
d
I’m finishing my proposal, that looks like this: https://github.com/soywiz/ktor-cio-clients/blob/8df022cddaf49e11f5a6895a950fd55f750ec626/ktor-server-circuitbreaker/test/io.ktor.experimental.circuitbreaker/CircuitBreakerTest.kt You define Services: a service has a name and a check for up. Then you wrap calls with that service and a block. That block is executed with a timeout and if that timeout happens, the service is marked as down and the check for up starts while throws a ServiceUnavailable in the meantime when using that service. You have to wrap each call to the service with circuitBreaker.wrap. In my case with my redis client it is trivial to generate another client with all the calls wrapped as in the example.
Let me check the vertex approach
d
I think in Ktor, instead of wrapping Future like they do, it could wrap a launched coroutine...
The only thing is that exception handling in Coroutines is a bit trickier... 🙃
d
What do you mean by “trickier”? Stacktraces, or something else?
d
If using only
suspend fun
, it's fine, and your example is very good. The problem starts when delegating blocking work to other context pools or to actor channels...
d
I see. What I usually do is to create wrapper suspend functions that call those APIs, it can map thenable promises to continuations and register cancellation handlers and so on
Then everywhere else I use those wrapped functions.
d
That's a good point 🙂, I guess that still makes it a bit flaky for end-users, at least until there are at least async db clients...
Which is one of the more common service endpoints that could block the event loop
d
In that repo you have a few wip & experimental pure kotlin async clients prepared for MPP already 🙂 Another mixed approach is to expose those wrappers as artifacts. So other people can consume other async libraries as plain suspending functions. That would be nicer for end-users.
I guess it is possible to automate that with code generation, by loading a library, introspecting public functions in classes returning for example Promises or with well-known asynchronous callbacks and generating suspend extension methods
then publish that artifact 🙂
d
Right, but most clients out there don't have any async callbacks built in, the only one I found so far is the Vert.x one... the other option is to wrap the calls in
suspend fun getX() = withContext(DBPool)
now that you mention that. But certain calls we have in our API, return a sort of acknowledgement that it'll defer a longer task to an
actor
channel... in that channel I access the service, if that hangs... then I'll be collecting tons of hanged coroutines, how will the circuit breaker handle this?
d
Well if you have a blocked thread, you are pretty fucked 🙂 in java there is no graceful way of terminating threads.
You should use asynchronous clients if possible
That’s one of the benefits of node. You have one single thread, and everything is guaranteed to be asynchronous. No race conditions related to threading, or concurrent collections, so one less level of complexity. You only have to deal with asynchronous race conditions. And when using the right primitives you usually don’t have problems. While with threading there are tons of threading issues starting with collections. Despite that, nowadays I think there are asynchronous clients for the JVM for almost everything I guess. And if you stick to stateless requests (eg. no websockets), you won’t have to deal with those problems frequently.
d
Also good point... so is there a way to use those Vert.x async db clients (I don't think there are others, although they're in planning https://blogs.oracle.com/java/jdbc-next:-a-new-asynchronous-api-for-connecting-to-a-database)
Thanks for all this! I'll try to look into all the points we spoke about again to re-evaluate our plans. Just that point of Vert.x component integration with Ktor might be nice, since I already have coroutine layers built over the db clients (mysql and postgres) and our repositories are all using them, the event bus might be a plus...
d
Nice 🙂 👍
d
Btw, is the Ktorio Redis client production-ready?
d
everything in that repository is experimental
d
Any plans to get official versions out in the near future?
d
I would like. That doesn’t depend on me. Also no specific timeframe for now. Also those are prototypes. So if they are not good enough, I would try to release them as separate artifacts by myself. They already work, except for the dynamodb client, and I did some stress tests to the Redis client already, but they will require some heavy testing before considering them production-ready. I plan to use them in personal projects though, so I will test them more in depth
👌🏼 1