Titanium: Different execution contexts are not multi-threaded? - multithreading

I am trying to use titanium execution contexts to produce parallel code execution between the main application context and others. I am using CreateWindow with a url property refers to a .js file inside "lib" folder. But by logging the execution on both iOS and Android devices it seems that different contexts are executed on the app main thread, no parallelism here.
My new context trigger inside my Alloy controller:
var win2 = Ti.UI.createWindow({
title: 'New Window',
url: 'thread.js',
backgroundColor:'#fff'
});
win2.open();
Ti.API.log('after open');
My thread.js contents:
Ti.API.log("this is the new context");
Ti.App.fireEvent("go" , {});
while(true)
{
Ti.API.log('second context');
}
This while loop apparently blocks the main context (my Alloy controller) waiting it to exit.
Any suggestions of how can I execute some code (mainly heavy sqlite db access) in background so that the UI be responsive? (Web workers are not a choice for me).

You could try to achieve the wanted behaviour with a setInterval() or setTimeout() method.
setInterval()[source]:
function myFunc() {
//your code
}
//set the interval
setInterval(myFunc,2000) //this will run the function for every 2 sec.
Another suggested method would be to fire a custom event when you need the background behavior since it is processed in its own thread. This is also suggested in the official documentation.

AFAIK, titanium is single threaded, because JavaScript is single threaded. You can get parallel execution with native modules, but you'll have to code that yourself for each platform.
Another option is to use web workers, but I consider that to be a hack.

Related

Why in this code, await is not blocking ui in flutter

In the default example app whenever you create new fultter project I just added the following code.
initState() {
super.initState();
loop();
}
loop() async {
while (true) {
await Future.delayed(Duration(milliseconds: 10));
print("count now:$_counter");
}
}
Why is the app UI is not getting blocked? I am able to click + button and the counter increases smoothly. Even if I change the delay to 10 sec, the UI is resposive.
Is the loop() runnning in different thread?but I know dart is single thread. How is it possible?
Where the loop function is running?
Can I use this technique to run background task for example checking id my sqflite table rows are synced with cloud etc???
Await calls are non-blocking.
The way this works is, while Dart is single-threaded, some Dart code delegate their implementation to the Dart VM.
Things like file reads or HTTP requests are performed outside of Dart (either by the browser or in c++), in a different thread.
So while Dart is single-threaded, it is still able to perform multiple tasks simultaneously without locking the UI.

How to handle watchOS CoreData background save correctly?

My watchOS app uses core data for local storage. Saving the managed context is done in background:
var backgroundContext = persistentContainer.newBackgroundContext()
//…
backgroundContext.perform {
//…
let saveError = self.saveManagedContext(managedContext: self.backgroundContext)
completion(saveError)
}
//…
func saveManagedContext(managedContext: NSManagedObjectContext) -> Error? {
if !managedContext.hasChanges { return nil }
do {
try managedContext.save()
return nil
} catch let error as NSError {
return error
}
}
Very rarely, my context is not saved. One reason I can think of is the following:
After my data are changed, I initiate a background core data context save operation.
But before the background task starts, the watch extension is put by the user into background, and is then terminated by watchOS.
This probably also prevents the core data background save to execute.
My questions are:
- Is this scenario possible?
- If so, what would be the correct handling of a core data background context save?
PS: On the iOS side, I do the same, but here it is possible to request additional background processing time using
var bgTask: UIBackgroundTaskIdentifier = application.beginBackgroundTask(expirationHandler: {
//…
application.endBackgroundTask(bgTask)
}
By now, I think I can answer my question:
If the watch extension is put by the user into background, the extension delegate calls applicationDidEnterBackground(). The docs say:
The system typically suspends your app shortly after this method
returns; therefore, you should not call any asynchronous methods from
your applicationDidEnterBackground() implementation. Asynchronous
methods may not be able to complete before the app is suspended.
I think this also applies to background tasks that have been initiated before, so it is actually possible that a core data background save does not complete.
Thus, the core data save should be done on the main thread. My current solution is the following:
My background context is no longer set up using persistentContainer.newBackgroundContext(), since such a context is connected directly to the persistentContainer, and when this context is saved, changes are written to the persistent store, which may take relatively long. Instead, I now set up the background context by
var backgroundContext = NSManagedObjectContext.init(concurrencyType: .privateQueueConcurrencyType)
and set its parent property as
backgroundContext.parent = container.viewContext
where container is the persistent container. Now, when the background context is saved, it is not written to the persistent store, but to its parent, the view content that is handled by the main thread. Since this saving is only done in memory, it is pretty fast.
Additionally, in applicationDidEnterBackground() of the extension delegate, I save the view context. Since this is done on the main thread, The docs say:
The applicationDidEnterBackground() method is your last chance to
perform any cleanup before the app is terminated.
In normal circumstances, enough time should be provided by watchOS. If not, other docs say:
If needed, you can request additional background execution time by
calling the ProcessInfo class’s
performExpiringActivity(withReason:using:) method.
This is probably equivalent to setting up a background task in iOS as shown in my question.
Hope this helps somebody!

angular 5 run different thread in a background

I am using angular 5 with pouchdb. When I save a user I need to show it immediately in the users list. Meanwhile a background thread must geolocate the users city and update its coordinates for that user.
The geolocation calculation takes a second or two to load that is why I am thinking of running in a background thread.
I looked into angular service worker, But I think its for getting files for offline.
I also looked angular cli web worker, But It did not mention how to call a background service and get a value back to main thread.
Is there a clear way to run a background thread in angular 5?
Using rxjs you can define and create an observable that do what you want :
myObservable = Observable.create(function (observer) {
if (navigator.geolocation) {
navigator.geolocation.getCurrentPosition(position => observer.next(position));
}
});
Then use it to get the desired value asynchronously :
myObservable.subscribe(pushedValue => console.log(pushedValue));
Here is a running example
This is not real multithread (not needed in this case in my opinion), for that you need to look more to web workers.
For Aangular 5 or under, I am using setTimout()
var _setTimeoutHandler = setTimout(() => { myfunction(){}})
Make sure you clear variable _setTimeoutHandler before quit to avoid resource leaking
I am also searching better way.

Application.GetResourceStream in non-ui thread

I have a problem with Silverlight application.
Suppose I have an xml file in resources stream. I get it as usual with something like this:
StreamResourceInfo sr =
Application.GetResourceStream(new Uri("uri goes there", UriKind.Relative));
var xml = XElement.Load(sr.Stream, LoadOptions.SetBaseUri);
And everything works just fine. But if the same code runs in the background thread (via async/await or, to be simple, in background worker) it always returns null.
I’ve heard about a bug in VS with similar problems (returning null) so I’ve tried to clean solution, delete obj folders etc. but nothing works — in background thread this code always return null for resources stream.
You can't access UI resources in background thread. Ideally you should access it in UI thread and pass it to background thread.

Where is "setTimeout" from JavaScript in Haxe?

Is there an implementation of setTimeout() and clearTimeout() in Haxe?
It's of course possible to use the Timer class, but for a one-shot execution it's not the best way, I guess.
For a one-shot execution I think that Timer.delay() is perfect. You can use the returned instance to stop the timer later:
var timer = haxe.Timer.delay(function() trace("Hello World!"), 250);
...
timer.stop();
You could also access the native setTimeout() with the js.html.Window extern:
var handle = js.Browser.window.setTimeout(function() trace("Hello World!"), 250);
...
js.Browser.window.clearTimeout(handle);
In case you're using the kha framework:
Kha modifies haxe.Timer to call kha.Scheduler, which in the end doesn't get the timestamps via setTimeout - it gets these via requestAnimationFrame().
This seems to not work while a tab is inactive, so it's not the same function while the tab is inactive.
I'm attempting a workaround, but at the moment, it doesn't give the same result as a native setTimeout()-JS does (although I found a workaround which I'll present for inclusion).

Resources