I wonder how could I write spring tests to assert logic chain which is triggered by 'SourcePollingChannelAdapter'.
What comes to my mind:
use Thread.sleep() which is really bad idea for tests
Have another test version of spring context where I will replace all pollable channels with direct ones. This requires much work.
Are there any common ways to force trigger poller within test?
Typically we use QueueChannel in our tests and wait for the messages via its receive(10000) method. This way, independently of the source of data, our test method thread is blocked until data has arrived.
The SourcePollingChannelAdapter is triggered by the TaskScheduler, therefore the whole flow logic is done within a separate thread from the test method. I mean that your idea about replacing channels won't help. The Thread.sleep() might have value, but QueueChannel.receive(10000) is much reliable because we really maximum wait only for those 10 seconds.
Another way to block test-case comes from the standard CountDownLatch, which you would countDown() somewhere in the flow and wait for it in the test method.
There is some other way to test: have some loop with short sleep period in between iteration and check some condition to exit and verify. That may be useful in case of poller and database in the end. So, we would perform SELECT in that loop until desired state.
You can find some additional info in the Reference Manual.
Related
The project I am working for is using Spring WebFlux. I came across a very odd issue.
The detail is that some of pieces of code are purely wrote in Reactor style (couples of Flux/Mono pipelines), however, in a inner publishers, I have to call a method where there is "Mono.block()" inside.
The weird thing I aware is that the whole service would become totally stuck, and when I captured a thread dump, I saw all those "nioEventLoopGroup-*" threads were hung.
A fun fact is that if I leverage a "simple" thread (new Thread(..)) to call the method (there is .block inside), everything works fine.
So my question is that, are those "nioEventLoopGroup-*" threads not allowed to call any blocking code.
Sorry for asking a dumb question, but it's blocking issue for now, so I am looking forward your insight.
Reactor, by default, uses a fixed size thread pool. When you use block(), the actual work needs to be done in some thread or another, which depends on the nature of the subscription and the Mono/Flux. Most likely a set of new tasks will be scheduled on the same scheduler, but block() will suspend its thread, waiting for those tasks to complete, so there is one fewer thread for those other tasks to be scheduled on. Evidently you have enough of these calls to exhauast the entire thread pool. All your block() calls are waiting for other tasks to complete, but there are no threads available for them to be run on.
There's no reason to call block() inside a mapping in a reactive stream. There are always other ways of achieving the same goal without blocking - flatMap(), zip() etc etc.
I am trying to schedule something than need to be ran every 200ms:
#Scheduled(every = "0.2s")
What's the recommended way to do it?
Is there a good reason why #Scheduled doesn't support rate under the second?
Unfortunately, this is not supported. The idea is that #Scheduled is only used for cron-like tasks with an accuracy of seconds (note that the Cron standard is designed to work with an accuracy of minutes).
However, you can inject a managed Vertx instance and make use of Vertx.setPeriodic(). But keep in mind that the handler is executed on an event loop thread and so the code should not block. If you really need to execute some blocking code then look at Vertx.executeBlocking().
The plan is to add an injectable managed ScheduledExecutorService for similar use cases.
I am creating an AWS step function where one of the step, let's call it step X, starts a variable number of lambdas. Since these lambda functions are long (they take between 1 and 10 minutes each to complete), I don't want to wait for them in step X. I would be spending money just for waiting. I therefore start them with InvocationType=Event so that they all run asynchronously and in parallel.
Once step X is done starting all these lambdas, I want my step function to wait for all these asynchronous functions to complete. So, a little like described here, I would create some kind of while loop in my step function. This loop would wait until all my asynchronous invocations have completed.
So the problem is: is it possible to query for the status of an AWS lambda that was started with InvocationType=Event?
If it is not possible, I would need my lambdas to persist their status somewhere so that I can poll this status. I would like to avoid this strategy since it does not cover problems that occur outside of my lambda (ex: out of memory, throttling exceptions, etc.)
An asynchronously invoked Lambda is a "fire and forget" use case. There's no straightforward way to get its result. I'm afraid you'll have to write your own job synchronization logic.
instead of polling,(which again is expensive), you can provide a callback, for the lambda to post back asynchronously. once you get all positives for all lambdas, then continue the process.
Since the question was initially posted, AWS added the support for dynamic parallelism in workflows. The need to manually start lambda functions and poll for their completion from within a step function is therefore now an anti-pattern.
Building a test plan in JMeter. I have different Transactions and each of them has number of HTTP samplers and "if conditions".
So basically each user might not perform the same action based on the "if condition". I want all the users to start performing the same transaction at the same time and also wait for the other users(Threads) if they have not reached to the current transaction.
I know that I can achieve this with the help of Synchronizing timer but somehow I am not able to achieve this with it.
How to achieve it with any possible method ?
PS - I just want the threads to start transaction at the same time. it does not matter if they performing same sampler or not.
I can suggest another approach,
You can use tearDown Thread Group,
execute after the test has finished executing its regular Thread Groups.
After all threads are done you execute tearDown and can execute anything you want, including Module Control which can reuse transaction from your main thread group
It is quite hard to guess what's going wrong without seeing your Test Plan structure. Just in case be aware that Timers obey Scoping Rules so if you want a request to be executed by N threads in parallel - you need to put the Synchronizing Timer as a child of this request.
See Using the JMeter Synchronizing Timer article for comprehensive information and example test plan.
I have what I assume is a common scenario, and while I believe I have a working solution, it feels like there's probably a better way.
The issue is that I need finer granularity than the Thread Group-level Action to be taken after a Sampler error behavior. Some of my samplers represent requests that would prevent further execution of a workflow on failure. In these cases, rather than barreling ahead with subsequent requests that a real user could not make and that would fail anyway, I want the thread to move on to the next iteration loop, starting from scratch, as it were. Other samplers represent requests that would continue to be made even if some of them failed. In these cases, I want the thread to keep going.
The method I'm using now, which is clunky but seems to work, is as follows: at the Thread-Group level I have set the Action to be taken after a Sampler error to be Continue. I assume this means that by default, if a Sampler fails, the thread will continue with the next instructions until it reaches the end.
This leaves requests that I want to block/halt/restart the workflow on a failure. The solution I have found is to follow each of these Critical Actions with an If Controller:
The condition !${JMeterThread.last_sample_ok} should resolve to true if the previous Sample failed. Within the If Controller, I have a Test Action to stop execution and start the next loop iteration of the thread:
I assume Go to next loop iteration means to start the thread over, assuming the Thread Group is set up with a loop count.
This set up seems to work, in that the thread starts over at the top of the tree each time a Sampler fails and is followed by this If/Action combo. Samplers that are not followed by this block do not halt execution on a failure.
This set up also seems very clunky, and annoying, since I'm copy-pasting this failure conditional all over the place. Is there a more elegant way of getting this behavior, or have I hit upon the more-or-less right way of doing this? Thanks!
Your solution is fine except for copy/paste as you say, so the solution is to use:
Test Fragment will contain your IfController:
Module Controller will point to it: