I'm trying to implement timeInMilliseconds Hystrix.
Added this definition to my method:
#HystrixCommand(fallbackMethod = "returnEmptyResponse",
commandProperties = {#HystrixProperty(name = "hystrix.command.default.execution.isolation.thread.timeoutInMilliseconds", value = "5000")})
Added to my class the relevant annotation: #EnableCircuitBreaker, and relevant dependencies.
I expected that if i didnt get response from my method after 5000 ms, returnEmptyResponse will be called.
It's not happen.
Did anyone know what can it be?
Related
I have a Grails 4 application providing a REST API. One of the endpoints sometimes fail with the following exception:
io.micronaut.http.client.exceptions.ReadTimeoutException: Read Timeout
at io.micronaut.http.client.exceptions.ReadTimeoutException.<clinit>(ReadTimeoutException.java:26)
at io.micronaut.http.client.DefaultHttpClient$10.exceptionCaught(DefaultHttpClient.java:1917)
at io.netty.channel.AbstractChannelHandlerContext.invokeExceptionCaught(AbstractChannelHandlerContext.java:297)
at io.netty.channel.AbstractChannelHandlerContext.invokeExceptionCaught(AbstractChannelHandlerContext.java:276)
at io.netty.channel.AbstractChannelHandlerContext.fireExceptionCaught(AbstractChannelHandlerContext.java:268)
at io.netty.channel.CombinedChannelDuplexHandler$DelegatingChannelHandlerContext.fireExceptionCaught(CombinedChannelDuplexHandler.java:426)
at io.netty.channel.ChannelHandlerAdapter.exceptionCaught(ChannelHandlerAdapter.java:92)
at io.netty.channel.CombinedChannelDuplexHandler$1.fireExceptionCaught(CombinedChannelDuplexHandler.java:147)
at io.netty.channel.ChannelInboundHandlerAdapter.exceptionCaught(ChannelInboundHandlerAdapter.java:143)
at io.netty.channel.CombinedChannelDuplexHandler.exceptionCaught(CombinedChannelDuplexHandler.java:233)
at io.netty.channel.AbstractChannelHandlerContext.invokeExceptionCaught(AbstractChannelHandlerContext.java:297)
at io.netty.channel.AbstractChannelHandlerContext.invokeExceptionCaught(AbstractChannelHandlerContext.java:276)
at io.netty.channel.AbstractChannelHandlerContext.fireExceptionCaught(AbstractChannelHandlerContext.java:268)
at io.netty.handler.timeout.ReadTimeoutHandler.readTimedOut(ReadTimeoutHandler.java:98)
at io.netty.handler.timeout.ReadTimeoutHandler.channelIdle(ReadTimeoutHandler.java:90)
at io.netty.handler.timeout.IdleStateHandler$ReaderIdleTimeoutTask.run(IdleStateHandler.java:505)
at io.netty.handler.timeout.IdleStateHandler$AbstractIdleTask.run(IdleStateHandler.java:477)
at io.netty.util.concurrent.PromiseTask$RunnableAdapter.call(PromiseTask.java:38)
at io.netty.util.concurrent.ScheduledFutureTask.run(ScheduledFutureTask.java:127)
at io.netty.util.concurrent.AbstractEventExecutor.safeExecute(AbstractEventExecutor.java:163)
at io.netty.util.concurrent.SingleThreadEventExecutor.runAllTasks(SingleThreadEventExecutor.java:405)
at io.netty.channel.nio.NioEventLoop.run(NioEventLoop.java:500)
at io.netty.util.concurrent.SingleThreadEventExecutor$5.run(SingleThreadEventExecutor.java:906)
at io.netty.util.internal.ThreadExecutorMap$2.run(ThreadExecutorMap.java:74)
at io.netty.util.concurrent.FastThreadLocalRunnable.run(FastThreadLocalRunnable.java:30)
at java.base/java.lang.Thread.run(Thread.java:834)
The endpoint uses micronaut http client to call other systems. The remote system takes a very long time to respond, causing the ReadTimeOutException.
Here is the code calling the remote Service:
class RemoteTaskService implements GrailsConfigurationAware {
String taskStepperUrl
// initializes fields from configuration
void setConfiguration(Config config) {
taskStepperUrl = config.getProperty('services.stepper')
}
private BlockingHttpClient getTaskClient() {
HttpClient.create(taskStepperUrl.toURL()).toBlocking()
}
List<Map> loadTasksByProject(long projectId) {
try {
retrieveRemoteList("/api/tasks?projectId=${projectId}")
} catch(HttpClientResponseException e) {
log.error("Loading tasks of project failed with status: ${e.status.code}: ${e.message}")
throw new NotFoundException("No tasks found for project ${projectId}")
}
}
private List<Map> retrieveRemoteList(String path) {
HttpRequest request = HttpRequest.GET(path)
HttpResponse<List> response = taskClient.exchange(request, List) as HttpResponse<List>
response.body()
}
}
I've tried resolving it using the following configuration in my application.yml:
micronaut:
server:
read-timeout: 30
and
micronaut.http.client.read-timeout: 30
...with no success. Despite my configuration, the timeout still occurs around 10s after calling the endpoint.
How can I change the read timeout duration for the http rest client?
micronaut.http.client.read-timeout takes a duration, so you should add a measuring unit to the value, like 30s, 30m or 30h.
It seems that the configuration values are not injected in the manually created http clients.
A solution is to configure the HttpClient at creation, setting the readTimeout duration:
private BlockingHttpClient getTaskClient() {
HttpClientConfiguration configuration = new DefaultHttpClientConfiguration()
configuration.readTimeout = Duration.ofSeconds(30)
new DefaultHttpClient(taskStepperUrl.toURL(), configuration).toBlocking()
}
In my case I was streaming a file from a client as
#Get(value = "${service-path}", processes = APPLICATION_OCTET_STREAM)
Flowable<byte[]> fullImportStream();
so when I got this my first impulse was to increase the read-timeout value. Though, for streaming scenarios the property that applies is read-idle-timeout as stated in the docs https://docs.micronaut.io/latest/guide/configurationreference.html#io.micronaut.http.client.DefaultHttpClientConfiguration
I'm trying to remove all query parameters from a URL with normalize-url package but getting some strange results.
I'm using the removeAllQueryParameters option as follows:
if (options.removeAllQueryParameters) {
for (const key of urlObj.searchParams.keys()) {
urlObj.searchParams.delete(key);
}
}
And using it as follows when calling the method to add the URL to the database:
{
let url = normalizeUrl(model.article.url,{removeAllQueryParameters: true});
callServerMethod({
name: 'addNewPost',
data: {
title: model.article.title,
url: url,
},
For the example URL: https://example.com?utm_source=test&utm_medium=test&utm_campaign=test
I'm getting the following result:
https://example.com?utm_campaign=test
Interestingly for the second example URL: https://example.com?utm_source=test
The result is https://example.com - correct.
The function is skipping the last parameter in a situation where there are more than 1 parameters to be removed.
Thanks in advance for any hints.
searchParams.keys() returns Iterator and it's bad idea to modify the source object while iterating it.
Simply make copy of keys into an array and iterate over it instead:
for (const key of [...urlObj.searchParams.keys()]) {
urlObj.searchParams.delete(key);
}
The following approach worked for me, however, I'm not sure if setting the urlObj.search like that is a good practice:
if (options.removeAllQueryParameters) {
urlObj.search = '';
}
I added the following to ~/.config/nix/overlays.nix, (as I wanted to workaround the issue involved with installing the current haskellPackages.greenclip package):
self: super:
{
haskellPackages = super.haskellPackages.override {
overrides = hsSelf: hsSuper: {
greenclip = self.haskell.lib.overrideCabal hsSuper.greenclip (oa: {
version = "3.2.0";
sha256 = "09ygvyrczxqsp2plwmwx021wmbq2vln9i4b5iaj0j26j7prykikq";
executablePkgconfigDepends = oa.executablePkgconfigDepends ++ [super.xorg.libXdmcp];
});
wordexp = self.haskell.lib.overrideCabal hsSuper.wordexp (oa: {
version = "0.2.2";
sha256 = "1mbcrq89jz0dcibw66w0jdy4f4bfpx4zwjfs98rm3jjgdikwdzb4";
});
};
};
}
Which resulted in the following when calling various nix related commands:
error: value is a function while a list was expected, at /nix/store/7wp1q60z6ha9wv8w0dfgr8ad2j9232ni-nixos-18.09.1834.9d608a6f592/nixos/pkgs/top-level/stage.nix:189:8
Why is this error occurring? How could I diagnose it further? (I'm assuming it's not actually an issue in the stage.nix file - even though the error reports it to be).
I was trying to use angular dart with websockets/server sent events and could not find any documentation/examples (there are some for angularJS but that seems very different for such things). A few things I tried also did not work.
Does anyone know how to do this?
Here is one version of what I tried and the error:
#NgController (
selector: "ACdistribution",
publishAs : "dstbn")
class ACDstbnController{
List <WtdPres> distbn;
void updateDstbn(List<WtdPres> newdstbn){
distbn = newdstbn;
}
final dstbnsrc = new EventSource("../dstbns")
..onMessage.listen((event){
List wps = JSON.decode(event.data);
List <WtdPres> newdistbn = wps.map((wp) => new WtdPres.fromJson(wp));
updateDstbn(newdistbn);
});
}
The error I got in pub build was:
web/provingground.dart:55:5:
'updateDstbn' is only available in instance methods.
updateDstbn(newdistbn);
^^^^^^^^^^^
There are limitations on what you can do on initializers for final fields.
Can you try to put this code inside the constructor
var dstbnsrc;
ACDstbnController() {
dstbnsrc = new EventSource("../dstbns")
..onMessage.listen((event){
List wps = JSON.decode(event.data);
List <WtdPres> newdistbn = wps.map((wp) => new WtdPres.fromJson(wp));
updateDstbn(newdistbn);
});
}
I'm trying to save a record like so:
var testRecord = new SecRecord(SecKind.GenericPassword)
{
CreationDate = DateTime.UtcNow,
MatchCaseInsensitive = false,
Service = "MyService",
Label = "MyService",
Account = "User",
Generic = NSData.FromString("test", NSStringEncoding.UTF8),
};
SecKeyChain.Add(testRecord);
...but I'm getting SecStatusCode.Param back when I run it in the simulator. According to the documentation, that code means "Invalid or incomplete parameters passed" but I don't see anything missing or unusual that others aren't doing with apparent success.
Even adding CreationDate, Invisible, Description, Comment, Accessible, and ValueData properties to the SecRecord (some as in this example) didn't help -- still getting SecStatusCode.Param.
Are there any non-obvious things that might cause a Param status code to be returned?
I had a lot of trouble trying to use the keychain. I finally got mine working to store user credentials in the app. Here is what I have:
SecRecord existingRec = new SecRecord (SecKind.GenericPassword) {
Service = Keychain.USER_SERVICE,
Label = Keychain.USER_LABEL
};
var record = new SecRecord (SecKind.GenericPassword) {
Service = Keychain.USER_SERVICE,
Label = Keychain.USER_LABEL,
Account = username,
ValueData = NSData.FromString (password),
Accessible = SecAccessible.Always
};
SecStatusCode code = SecKeyChain.Add (record);
if (code == SecStatusCode.DuplicateItem) {
code = SecKeyChain.Remove (existingRec);
if (code == SecStatusCode.Success)
code = SecKeyChain.Add (record);
}
Keychain is a static class with constants so I don't have to retype the strings.
The only thing different between yours and mine is the CreationDate/MatchCaseInsensitive properties and the encoding for NSData. Maybe try it without those and see if it works? If so, add them back separately and see what gives the problem.
This might be because you are running on the simulator - in that case you need to add an Entitlements plist in the project options for your current build config in order to make keychain access work.