How Do You Add A Timeout When Expecting Events In Corda Tests? - corda

During Corda testing with the DriverDSL you can wait for state updates.
e.g.
expectEvents(aliceVaultUpdates, true, () ->
expect(cashVaultUpdateClass, update -> true, update -> {
System.out.println("Alice got vault update of " + update);
Amount<Issued<Currency>> amount = update.getProduced().iterator().next().getState().getData().getAmount();
assertEquals(DOLLARS(1000), Structures.withoutIssuer(amount));
return null;
})
);
How do you add a timeout so the test doesn't wait forever when the expected update doesn't happen?

I think you could just use Junit to do this?
here's an example.
#Test(timeout = 500)
public void testInfiniteTametakingLoop() throws InterruptedException
{
while (true)
{
Thread.currentThread().sleep(1000);
}
}
source: https://howtodoinjava.com/junit/how-to-force-timeout-in-jnuit-testcase-execution/

Related

Multiple chained API calls to fetch data, but doOnNext of PublishSubject is never reached

I have a problem to understand a chained "RXJava-Retrofit" API call. I got inspired by this and implement this class named ObservationLoader to load the data from the API bucket per bucket. When the end of data is reached the API sends a endOfRecords=true:
public Observable<PageObject<Observation>> getAllObservationDataByRegion(long taxonKey,
String regionId) {
final PublishSubject<PageObject<Observation>> subject = PublishSubject.create();
return subject.doOnSubscribe(disposable -> {
this.getData(taxonKey, regionId, 0).subscribe(subject);
})
.doOnNext(observationPageObject -> {
if (observationPageObject.isEndOfRecords()) {
// -> list is completely loaded
subject.onComplete();
} else {
int nextOffset = observationPageObject.getOffset() + 1;
this.getData(taxonKey, regionId, null, nextOffset).subscribe(subject);
}
})
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread());
}
private Observable<PageObject<Observation>> getData(long id,
String regionId,
int offset) {
// Get your API response value
return this.api.getObservations(id, regionId, ObservationLoader.PAGE_LIMIT, offset);
}
In my Android fragment HomeFragment I subscribe to the ObservationLoader:
ObservationLoader loader = new ObservationLoader(this.getApi());
Observable<PageObject<Observation>> observable = loader
.getAllObservationDataByRegion(this.getSelectedSpecies(), this.getSelectedRegion());
observable.subscribe(new Observer<PageObject<Observation>>() {
#Override
public void onSubscribe(Disposable d) {
Log.i(TAG, "ON_SUBSCRIBE");
}
#Override
public void onNext(PageObject<Observation> observationPageObject) {
Log.i(TAG, "ON_NEXT");
}
#Override
public void onError(Throwable e) {
Log.i(TAG, "ERROR = " + e.getMessage());
}
#Override
public void onComplete() {
Log.i(TAG, "COMPLETED");
}
});
I can see that the onSubscribe() and doOnSubscribe() are called and even the getData() is reached. I assume the API is responding correctly (a previous attempt attempt with recursion worked fine). But I never reached the doOnNext function. The observer goes straight to onComplete() and no data is received. What could be the reason?
When doOnSubscribe runs, the doesn't see any consumers yet so if getData is synchronous, there won't be any first results to trigger further results. Also if getData ends, it will complete the setup so the next getData call in doOnNext will push to an already terminated subject, ingoring all data.
You'll need a differently organized feedback loop:
// we loop back the nextOffset, in a thread-safe manner
Subject<Integer> subject = PublishSubject.<Integer>create()
.toSerialized();
// bootstrap with 0 and keep open for more offsets
subject.mergeWith(Observable.just(0))
// get the data for the current offset
.concatMap(nextOffset -> getData(taxonKey, regionId, nextOffset)
.subscribeOn(Schedulers.io())
)
// if the response is end of records, stop
.takeWhile(observationPageObject -> !observationPageObject.isEndOfRecords())
// otherwise not end of records, feedback the new offset
.doOnNext(observationPageObject ->
subject.onNext(observationPageObject.getOffset() + 1)
)
// get the data on the main thread
.observeOn(AndroidSchedulers.mainThread());

How do I handle AX timeouts where the operation continues on? Abort not working?

I have a custom AX service operation that can take 5+ minutes to complete and I'm trying to figure out how to abort it from my .NET application, but aborting the client doesn't seem to do anything?
The problem is if I call the operation and the service times out, the AX operation continues on until completion, so I lose visibility to the results (success/failure). An example being a long-running posting operation where I don't know if it posted successfully or not.
I've created a simple demo app where I can't seem to get the operation to abort. In the below code I just create a transaction (ttsbegin/ttscommit), insert into a table at start, sleep, insert into table at end.
Sample AX X++ Service Code:
[SysEntryPointAttribute(true)]
public str callAXTimeDelay(int _sleepSeconds)
{
Table1 table1;
ttsBegin;
table1.clear();
table1.SleepData = strFmt("STARTED: %1", DateTimeUtil::utcNow());
table1.insert();
ttsCommit;
sleep(_sleepSeconds * 1000);
ttsBegin;
table1.clear();
table1.SleepData = strFmt("COMPLETED: %1", DateTimeUtil::utcNow());
table1.insert();
ttsCommit;
return strFmt("COMPLETED: %1", DateTimeUtil::utcNow());
}
Then when I call it from .NET, the abort doesn't seem to work? Start/Complete records are still inserted into table1 even though the abort is called before the 15 seconds have completed?
Sample .NET code:
internal class Program
{
static void Main(string[] args)
{
new Program().Run();
Console.WriteLine("Ended, press any key to exit...");
Console.ReadKey();
}
public void Run()
{
AXServicesClient axClient15Sec = new AXServicesClient();
AXServicesClient axClient5sec = new AXServicesClient();
var job15sec = DoLongRunningCall(axClient15Sec, 15);
var job5sec = DoLongRunningCall(axClient5sec, 5);
try
{
var result = Task.Run(() => Task.WhenAny(job15sec, job5sec)).GetAwaiter().GetResult();
if (result == job15sec)
{
Console.WriteLine("job15sec finished first, aborting job5sec");
axClient5sec.Abort();
}
else if (result == job5sec)
{
// This code gets executed because the 5 second job completed and
// it tries to cancel the 15-sec job, but the table ends up with data!
Console.WriteLine("job5sec finished first, aborting job15sec");
axClient15Sec.Abort();
}
}
catch (Exception e)
{
Console.WriteLine("Exception: " + e.Message);
axClient15Sec.Abort();
axClient5sec.Abort();
}
axClient15Sec.Close();
axClient5sec.Close();
}
public async Task<string> DoLongRunningCall(AXServicesClient client, int seconds)
{
var result = await client.callAXTimeDelay(new CallContext
{
Company = "ABCD",
Language = "en-us"
}, seconds);
return result.response;
}
}

toCompletableFuture() stucks for asynchronous cache

Hello there I am trying to force a promise to end to get the result from it but it just stucks on loading.
public class CacheController extends Controller {
private AsyncCacheApi cache;
public Result cache()
{
String test = "nice";
cache.set("item.key", test, 15);
Customer user = new Customer("Ana", 12);
CompletionStage<Done> result = cache.set(user.getName(), user);
block(result);
return ok("Cached");
}
public Result checkCache() throws Exception
{
Logger.info("start");
//CompletionStage<String> news = cache.get("item.key");
//news.thenRun(() -> System.out.println("works"));
CompletionStage<Customer> result = cache.get("Ana");
Logger.info("step 1");
Logger.info(cache.get("Ana").toString());
Logger.info("Step 2");
Customer c = block(result);
Logger.info("Step 3 " + c.getName());
//result.thenRun(() -> setUser(result)).thenRun(() -> Logger.info(user.getName() + " " + user.getAge()));
return ok("cancan");
}
private <T> T block(CompletionStage<T> stage) {
try {
return stage.toCompletableFuture().get();
} catch (Throwable e) {
throw new RuntimeException(e);
}
}
}
When trying to load the page it gets stuck after step2 at line 56: Customer c = block(result); by my guesses
Any ideas to fix it?
#Codrin
I had the same problem. But, see https://www.playframework.com/documentation/2.6.x/JavaCache#Setting-the-execution-context
By default, all Ehcache operations are blocking, and async implementations will block threads in the default execution context.
Maybe CompletableFuture.get() gets stuck because it is executed in the same thread with the caller.
Referring to the linked page, I added snippet below to my application.conf and it worked.
play.cache.dispatcher = "contexts.blockingCacheDispatcher"
contexts {
blockingCacheDispatcher {
fork-join-executor {
parallelism-factor = 3.0
}
}
}

SignalR disconnect function not recognized on client

public Task Disconnect()
{
var context = new HaiTaxiContainer();
var driver = context.OperatorEmployeeSet.Where(o => o.ConnectionId == Context.ConnectionId).FirstOrDefault();
driver.IsWorking = false;
driver.OperatorWorkingHistory.Add(new OperatorWorkingHistory
{
IsWorking = false,
Time = DateTime.Now
});
return Clients.leave(Context.ConnectionId, DateTime.Now.ToString()); ;
}
if (chat.disconnect!=null){
chat.disconnect(function () {
alert('Server has disconnected');
});
alert('Server disconnect==smt');
}else{
alert('Server disconnect==null');
}
The client chat.disconect is null. ANy ideeas why?
Based on your code it is hard to tell what you are actually doing - e.g., what is chat ? However, I think you should take a look at this related question / answer: https://stackoverflow.com/a/9122242/700926 about "How to determine server disconnection from SignalR client?" - it might be useful.

Enable no timeout for one specific page

I have a page that doing something, it can take 1,2 hours or even more...
After a while I get request timed out, I want that this specific page will NOT get request timed out - ever(or at least 24 hours).
How do I do it?
Thanks.
You can make a thread with a signal in it to know it its still running or not.
I suggest to use a mutex signal because is the only one that can be the same across many pools and threads.
The thread code can be:
public class RunThreadProcess
{
// Some parametres
public int cProductID;
// my thread
private Thread t = null;
// start it
public Thread Start()
{
t = new Thread(new ThreadStart(this.work));
t.IsBackground = true;
t.SetApartmentState(ApartmentState.MTA);
t.Start();
return t;
}
// actually work
private void work()
{
// while the mutex is locked, the thread is still working
Mutex mut = new Mutex("WorkA");
try
{
mut.WaitOne();
// do thread work
all parametres are available here
}
finally
{
mut.ReleaseMutex();
}
}
}
And you call it as
Mutex mut = new Mutex("WorkA");
try
{
if(mut.WaitOne(1000))
{
// release it here to start it from the thread as signal
mut.ReleaseMutex();
// you start the thread
var OneAction = new RunThreadProcess();
OneAction.cProductID = 100;
OneAction.Start();
}
else
{
// still running
}
}
finally
{
mut.ReleaseMutex();
}

Resources