Anyway to stop a sequence of actions? - ibm-cloud

I sort of like the idea of sequences, but I would like to be able to have an action basically stop the sequence. The idea is to have an action which filters the incoming message, and if it doesn't meet certain criteria it would return false or something and essentially stop the processing of the sequence.
I could probably incorporate a convention myself, but wondered if there was a mechanism.

You can fail the filtering action by returning a rejected Promise instead of a resolved one. That will fail the action and thus break the sequence at that point.
Here's a short example that might help:
function main(args) {
if(args.myValue == "myValue") {
return Promise.resolve({...});
} else
return Promise.reject({...});
}
}

Related

Wait for a *specific* (single) XCTestExpectation with a completion handler?

Has anyone managed to wait for a specific, single, XCTestExpectation with completion handler (XCWaitCompletionHandler or equivalent) similar to that of (waitForExpectations:timeout:handler)[https://developer.apple.com/documentation/xctest/xctestcase/1500748-waitforexpectations].
I want to wait for just one specific expectation, but I would like to know if it timed out. The XCWaitCompletionHandler gives me that information. But there are no properties on the expectation itself flagging whether it timed out or not.
(yes this is a rather advanced use case...)
Create an XCTWaiter and use wait(for:timeout:), which returns a XCTWaiter.Result, which you can then assert is/is not .timedOut if you wish, or otherwise act on the result. By using XCTWaiter, you can have an expectation time out without the test automatically failing.
let result = XCTWaiter().wait(for: [expectation], timeout: 5)
if result == .timedOut { ... }

How To Say "When The Count Gets To This Number Execute This Function"?

Before I reload a table I want to know that all of the tasks that were saving in the background are done saving. I have 5 different saveInBackground functions that must complete before I make a new PFQuery. My thought right now is to say:
object.saveInBackgroundWithBlock({ (Success: true, error) -> Void in
count ++
})
Then, once the count gets to a certain number to perform the query. I don't want to use if because if the network is taking too long to process the save request. Would a while statement work? Such as:
while count < 0 {
continue
} else if count == 5 {
self.fetchSecondaryObjects()
}
Ideally I would be using a real-time data engine to power my application but I'm having trouble locating one that I can use as I only write in Swift. If this exists out there and you know of it, I'd love to know about it.
Just do the check each time you increment. It's really very low overhead, only five comparisons.
object.saveInBackgroundWithBlock({ (Success: true, error) -> Void in
count ++;
if count == 5 {
self.fetchSecondaryObjects()
}
})
Unless I'm missing some reason you can't do that, it seems like the simplest solution. Better than running an infinite loop.
Generally I try not to use while in such cases because one can easily get stuck in them if you're somehow of in your logic. Why don't you just use something like that:
if count >= xyz

QApplication::processEvents never returns

In my application I need to wait until external program (using QProcess) is finished. I want to keep the application responsible so blocking methods are unacceptable.
Also I need to disallow user input. I've tried to make QEventLoop and exec it with QEventLoop::ExcludeUserInputEvents flag, but as documentation says it only delays an event handling:
the events are not discarded; they will be delivered the next time processEvents() is called without the ExcludeUserInputEvents flag.
So I implemented simple event filter and install it on qApp (the idea is took from Qt Application: Simulating modal behaviour (enable/disable user input)). It works well, but sometimes QApplication::processEvents function never returns even if I specify the maximum timeout. Could anyone help me to understand for what reasons it periodically happens?
class UserInputEater : public QObject
{
public:
bool eventFilter(QObject *object, QEvent *event)
{
switch(event->type())
{
case QEvent::UpdateRequest:
case QEvent::UpdateLater:
case QEvent::Paint:
return QObject::eventFilter(object, event);
default:
return true;
}
}
};
-
UserInputEater eventEater;
qApp->installEventFilter(&eventEater);
QProcess prc;
prc.start("...");
while(!prc.waitForFinished(10))
{
if(qApp->hasPendingEvents())
{
// Sometimes it never returns from processEvents
qApp->processEvents(QEventLoop::AllEvents, 100);
}
}
qApp->removeEventFilter(&eventEater);
UPD: Seems like it depends of the timeout value for QProcess::waitForFinished.
I guess you are filtering some useful events (for example, QEvent::SockAct could be involved). Try to add some debug output and find out which event types you're actually filtering. Or it might be better to specify the black list of events you want to block instead of white list of events you want to allow. See this answer.
Also you shouldn't use return QObject::eventFilter(object, event);. You should use return false. All other event filters will be called automatically.
This solution however seems weird and unreasonable to me because you can just call setEnabled(false) for your top level widget to block user input, and then you can use QApplication::processEvents without any flags.

Play 1.2.3 framework - Right way to commit transaction

We have a HTTP end-point that takes a long time to run and can also be called concurrently by users. As part of this request, we update the model inside a synchronized block so that other (possibly concurrent) requests pick up that change.
E.g.
MyModel m = null;
synchronized (lockObject) {
m = MyModel.findById(id);
if (m.status == PENDING) {
m.status = ACTIVE;
} else {
//render a response back to user that the operation is not allowed
}
m.save(); //Is not expected to be called unless we set m.status = ACTIVE
}
//Long running operation continues here. It can involve further changes to instance "m"
The reason for the synchronized block is to ensure that even concurrent requests get to pick up the latest status. However, the underlying JPA does not commit my changes (m.save()) until the request is complete. Since this is a long-running request, I do not want to wait until the request is complete and still want to ensure that other callers are notified of the change in status. I tried to call "m.em().flush(); JPA.em().getTransaction().commit();" after m.save(), but that makes the transaction unavailable for the subsequent action as part of the same request. Can I just given "JPA.em().getTransaction().begin();" and let Play handle the transaction from then on? If not, what is the best way to handle this use-case?
UPDATE:
Based on the response, I modified my code as follows:
MyModel m = null;
synchronized (lockObject) {
m = MyModel.findById(id);
if (m.status == PENDING) {
m.status = ACTIVE;
} else {
//render a response back to user that the operation is not allowed
}
m.save(); //Is not expected to be called unless we set m.status = ACTIVE
}
new MyModelUpdateJob(m.id).now();
And in my job, I have the following line:
doJob() {
MyModel m = MyModel.findById(id);
print m.status; //This still prints the old status as-if m.save() had no effect...
}
What am I missing?
Put your update code in a job an call
new MyModelUpdateJob(id).now().get();
thus the update will be done in another transaction that is commited at the end of the job
ouch, as soon as you add more play servers, you will be in trouble. You may want to play with optimistic locking in your example or and I advise against it pessimistic locking....ick.
HOWEVER, looking at your code, maybe read the article Building on Quicksand. I am not sure you need a synchronized block in that case at all...try to go after being idempotent.
In your case if
1. user 1 and user 2 both call that method and it is pending, then it goes to active(Idempotent)
If user 1 or user 2 wins, well that would be like you had the synchronization block anyways.
I am sure however you have a more complex scenario not shown here, BUT READ that article Building on Quicksand as it really changes the traditional way of thinking and is how google and amazon and very large scale systems operate.
Another option for distributed transactions across play servers is zookeeper which the big large nosql guys use BUT only as a last resort ;) ;)
later,
Dean

How to use the new BufferWithTimeOrCount in Rx that returns IObservable<IObservable<T>> instead of IObservable<IList<T>>

On Windows Phone 7 there is a new version of the BufferWithTimeOrCount extension method for IObservable that returns a "stream of streams" instead of the previous "stream of lists". I'm having difficulty trying to use either the new or old methods, so maybe I just don't understand how it works, but my goal is to create a stream that only fires when an existing stream matches a specified time based pattern during the previous 2 touch events. So far I have created streams for TouchUp and TouchDown (see related question) and In pseudo code I want something like:
//BufferLast2 should contain the last 1 or 2 touch events that occurred in the last 500ms. If no touches occurred this should return an empty set
var BufferLast2 = TouchDown.Merge(TouchUp).BufferWithTimeOrCount(TimeSpan.FromSeconds(0.5), 2);
//Use BufferLast2 to detect tap (TouchDown then TouchUp occuring in less than 0.5s)
var TouchTap = from touch2 in BufferLast2
where touch2.Count == 2 && touch2.First().Action == TouchAction.Down && touch2.Last().Action == TouchAction.Up
select touch2.First(); //returns initial TouchDown event
//Use BufferLast2 to detect Hold (TouchDown with no TouchUp occuring in 0.5s)
var TouchHold = from touch2 in BufferLast2
where touch2.Count == 1 && touch2.First().Action == TouchAction.Down
select touch2.First(); //returns initial TouchDown event
When using the "Stable" Microsoft.Phone.Reactive version of Rx that is built into the ROM calling IObservable<Class>.BufferWithTimeOrCount(...) returns a IObservable<IList<Class>>, which is pretty easy to work with using the standard list operators (as outlined above), but for some reason BufferLast2 was always returning two down events instead of the Down->Up sequence that I expected.
I figured it might be a bug in the code, so I tried adding a reference to the latest version of Rx and used the Observable Extensions from C:\Program Files (x86)\Microsoft Cloud Programmability\Reactive Extensions\v1.0.2838.0\WP7\System.Reactive.dll in which BufferWithTimeOrCount(...) returns a IObservable<IObservable<Class>>. This makes simple filters like Where x.Count == 2 or Where x.First().P == ... much harder to write. I haven't actually figured out how to do a simple filter like x.Count() == 2 on this return value without creating a completely separate subscription or Subject object, which seams way too complex. It's probably a simple error like my last question (all I needed was a Where clause :-P) but it is really driving me bonkers. Any help?
Changing the api makes the buffering look more Rx-y and fits with their Window operator implementation (wouldn't be surprised if using reflector you'd be able to see the Buffer operators using Window). I would think there's probably a variety of reasons that they've changed it. I'm not going to second guess them as they're a lot smarter than me!
So here's my stab at a solution. There may be a cleaner way to get what you're after but i'd probably implement my own extention method to buffer into a list. Maybe something like:
public static class BufferToList
{
public static IObservable<IEnumerable<TSource>> BufferToList<TSource>(this IObservable<TSource> source)
{
return Observable.CreateWithDisposable<IEnumerable<TSource>>(observer =>
{
var list = new List<TSource>();
return source.Subscribe(list.Add,
observer.OnError,
() =>
{
observer.OnNext(list);
observer.OnCompleted();
});
});
}
}
Then something like:
TouchDown.Merge(TouchUp)
.BufferWithTimeOrCount(TimeSpan.FromSeconds(0.5), 2)
.Select(bufferedValues => bufferedValues.BufferToList())
.Subscribe(OnBufferOpen)
private void OnBufferOpen(IObservable<IEnumerable<IEvent<IEventArgs>>> bufferedListAsync)
{
bufferedListAsync.Where(list => list.Count() == 2);
}
I suggest if you want a full explanation of why they've changed the api, go and ask the question over on the rx forums on msdn
The latest release of Rx, v1.0.2856.0, provides both buffers and windows. For the buffers, we restored the original signatures, based on IList. The corresponding window operators will return nested observable sequences.
The way the Buffer* operators are implemented is by composing the corresponding Window* operator with the new ToList extension method that takes an IObservable into an IObservable>. All the Buffer* operator does is invoke this new ToList operator in a SelectMany selector.