I noticed that a blocking gPRC call might be blocked for a long, long time, if not for ever.
I checked and found the following page:https://grpc.io/docs/guides/concepts.html#deadlines
However, the page does not tell the default deadline/timeout value for Java.
So, I am wondering if there is a default java value.
I probably have to set a deadline value for all the calls, if not. Which is inconvenient...
There is no default deadline, in gRPC for any language. If there are network failures and keepalive is enabled on client-side, the call will eventually fail. But if the server takes an unbounded amount of time, then the client may wait an unbounded amount of time.
It is equivalent to "infinity" according to this issue https://github.com/grpc/grpc-java/issues/1495
Just like #Eric Anderson said, there's no default deadline. But, it's highly recommended to set one for each RPC in the client and service provider should also specify the longest deadline they support as mentioned in the blog: https://grpc.io/blog/deadlines
In general, when you don’t set a deadline, resources will be held for all in-flight requests, and all requests can potentially reach the maximum timeout. This puts the service at risk of running out of resources, like memory, which would increase the latency of the service, or could crash the entire process in the worst case.
To avoid this, services should specify the longest default deadline they technically support, and clients should wait until the response is no longer useful to them. For the service this can be as simple as providing a comment in the .proto file. For the client this involves setting useful deadlines.
Related
I have a project that reads data from many different providers; some via SOAP, some via HTTP, etc. Some of these providers also have a restriction on the number of concurrent connections to them. For example, provider A may allow unlimited connections, provider B may only allow 2, and provider C may allow 5.
I'm decent with Micronaut, but I'm unaware of anything built into it that would allow me to limit connections to specific URLs as necessary. So, my first thought is to create a per-provider thread limit (perhaps using RxJava's scheduler system? I believe you can create custom ones using Java's Executor class) and let that do the work of queuing for me. I think I could also go the more manual route of creating a ConcurrentMap and storing the number of active connections in that, but that seems messier and more error-prone.
Any advice would be greatly appreciated! Thanks!
Limiting thread numbers is suitable only if the network connections are made by threads, that is, synchronously. But Micronaut also can make asynchronous connections, and then limiting the number of threads won't work. Better do limiting the number of connections directly. Create an intermediate proxy object with has the same interface as Micronaut and passes all incoming requests to the real Micronaut. It also has a parameter - limit, and when a request is passed, decrements the limit. when the limit becomes 0, the proxy object stops passing requests, keeping them in an input queue. As soon as a request is finished, it signals the proxy object and it passes one request from the input queue, if any, or just increments the limit.
The simplest implementation of the proxy is a thread with BlockingQueue for input requests and Semaphore for limit. But if there are many providers and creating a thread for each provider is expensive, the proxy can be implemented as an asynchronous object.
For setting up the timeouts while making REST calls we should specify both these parameters but I'm not sure why both and exactly what different purpose they serve. Also, what if we set only one of them or both with different value?
CONNECT_TIMEOUT is the amount of time it will wait to establish the connection to the host. Once connected, READ_TIMEOUT is the amount of time allowed for the server to respond with all of the content in a give request.
How you set either one will depend on your requirements, but they can be different values. CONNECT_TIMEOUT should not require a large value, because it is only the time required to setup a socket connection with the server. 30 seconds should be ample time - frankly if it is not complete within 10 seconds it is too long, and the server is likely hosed, or at least overloaded.
READ_TIMEOUT - this could be longer, especially if you know that the action/resource you requested takes a long time to process. You might set this as high as 60 seconds, or even several minutes. Again, this depends on how critical it is that you wait for confirmation that the process completed, and you'll weigh this against how quickly your system needs to respond on its end. If your client times out while waiting for the process to complete, that doesn't necessarily mean that the process stopped, it may keep on running until it is finished on the server (or at least, until it reaches the server's timeout).
If these calls are directly driving an interface, then you may want much lower times, as your users may not have the patience for such a delay. If it is called in a background or batch process, then longer times may be acceptable. This is up to you.
I have to use Java ThreadPoolExecutor in one of my component in Android. I was searching the use of allowCoreThreadTimeout( ).
I have read the Java & Android docs related.
But I didn't get any useful implementation scenario of the method.
Can someone please help me??
This method allows you to specify whether to terminate the core thread if there is no incoming task within the thread keep alive time. This is related to other configuration like, setCorePoolSize(), setKeepAliveTime(..)
When you are creating a thread pool and idle threads exist in the pool even though there is no task is running. It is costly to keep these thread alive. If you want get rid of these when you have no task to execute, this method is useful. You need to pass true value then they will be die after the keep alive time.
In Summary:
allowCoreThreadTimeOut(true) // Could save memory compromising performance
allowCoreThreadTimeOut(false) // Comsume memory but high performance
Permitting core threads to timeout allows an application to efficiently handle 'bursty' traffic. Consider a scenario where an enterprise application is idle during business hours but receives a burst of many requests at the end of the day.
One way of efficiently handling this scenario would be to enable allowCoreThreadTimeout() and set coreThreads = maxThreads to some appropriately high value. During that peak time your thread pool would scale up to handle the traffic and then afterwards scale back down to zero, freeing up server resources.
public void allowCoreThreadTimeOut(boolean value)
This is greatly explained in javadoc
Sets the policy governing whether core threads may time out and terminate if no tasks arrive within the keep-alive time, being replaced if needed when new tasks arrive.
When false, core threads are never terminated due to lack of incoming tasks. When true, the same keep-alive policy applying to non-core threads applies also to core threads. To avoid continual thread replacement, the keep-alive time must be greater than zero when setting true. This method should in general be called before the pool is actively used.
It's useful in situations when you can not call ThreadPoolExecutor.shutdown method explicitly at the end of your object lifecycle (framework doesn't provide "onClose" hook, for example), but you need to use ThreadPoolExecutor. In this case, without allowCoreThreadTimeout(true) method call, ThreadPoolExecutor's core threads will block GC of your object and cause memory leaks.
Here's how this scenario referenced in "Finalization" section of the ThreadPoolExecutor documentation:
A pool that is no longer referenced in a program AND has no remaining
threads will be shutdown automatically. If you would like to ensure
that unreferenced pools are reclaimed even if users forget to call
shutdown(), then you must arrange that unused threads eventually die,
by setting appropriate keep-alive times, using a lower bound of zero
core threads and/or setting allowCoreThreadTimeOut(boolean).
you can check parse implementation for android sdk, it's really nice.
We would like to monitor HTTP error codes (e.g. per minute) for later graphing.
How can we expose HTTP return (error) codes with JMX?
Are there code samples or have you done something like that? Is this contained in Tomcat per default?
About the implementation: Should the code increase a JMX counter and set it to 0 every minute? Thanks for ideas.
If you're looking to derive rates of errors and graph those, you're better off having the server return a total count of errors. That way the client can then derive a rate independent of the server (e.g. per minute/per hour/per day).
More importantly, you won't miss any temporary surges in the data. If the server is deriving a rate and your client process doesn't pick it up (if it's not monitoring at that particular time, say), then it's lost forever. Whereas maintaining a count will record the total number of errors.
SNMP agents (and similar) take this approach, allowing clients to monitor and derive values as they see fit.
Add a JMX bean which has one field per HTTP error you care about. Increment each field as errors drop in. The JMX console will turn that into a nice curve. I wouldn't reset the value but that mostly depends on what features your console has to show a statistic on a value.
I am building an application that reaches out to a FHIR API that implements paging, and only gives me a maximum of 100 results per page. However, our app requires the aggregation of these pages in order to hand over metadata to the UI about the entire result set.
When I loop through the pages of a large result set, I get HTTP status 429 - Too many requests. I am wondering if handing off these requests to a kafka service will help me get around this issue and maybe increase performance. I've read through the Intro and Use Cases sections of the Kafka documentation, but am still unclear as to whether implementing this tool will help.
You're getting 429 errors because you're making too many requests too quickly; you need to implement rate limiting.
As far as whether to use Kafka, a big part of that is whether your result set can fit in memory. If you can fit it in memory, then I would really suggest avoiding bringing in a separate service (KISS). If not, then yes, you can use Kafka. But I'd suggest taking a long think about whether you can use a relational datastore, because they're much more flexible. Or maybe even reading/writing directly to the disk
I were you, before I look into Kafka, I would try to solve why you are getting a 429 error. I would not leave that unnoticed. I would try to see how I am going to solve that.
I would looking into the following:
1) Sleep your process. The server response usually includes a Retry-after header in the response with the number of seconds you are supposed to wait before retrying.
2) Exponential backoff If the server's response does not tell you how long to wait, you can retry your request by inserting pauses by yourself in between.
Do keep it mind, before implementing sleep, it warrants extensive testing. You would have to make sure that your existing functionality does not get impacted.
To answer your question if Kafka would help you or not, the answer is it may or may not, with the limited info I can get from your question. Do understand that implementing Kafka would change your network architecture. You are bringing in a streaming platform to the equation. You would most probably implement caching which would aggregate your results. But at the moment all these concepts are at a very holistic level. I would suggest that you first ought to solve the 429 error and then warrant if a proper technical reason is present to implement Kafka which would improve your website's performance.