Recovering a blocking -runModal?

14 views
Skip to first unread message

Luke

unread,
Jan 28, 2023, 5:12:15 PM1/28/23
to Cappuccino & Objective-J
Cappuccino is implemented differently than Cocoa, presumably mostly for good reasons (although perhaps there are also some things done for expediency in the initial version).

One example is that -runModal for CPAlert is non-blocking and you have to pick up the user response from a delegate asynchronously to launching the alert dialog. 

While not a great hardship, structuring the code in 'continuation style', where half of the logic sets up the modal and launches it, and another half picks up with logic having to do with the response, I was wondering if it was possible to recover a blocking interface, which would return the response code like NSAlert's -runModal.

One way you could do this in Cocoa is to create a runLoop that will block a call, while events still proceed in the 'inner loop', until you determine that conditions have been met to return on the original call (in which case you terminate the nested runLoop and the stack pops back with the original code flow.  

I've checked out the foundation sources in Cappuccino and it seems that it has a rather 'truncated' runLoop model, so this strategy is probably not possible. 

Is there any other way I can block and continue processing events in a way that would enable me to put a synchronous wrapper around -runModal?
  

Keary Suska

unread,
Jan 28, 2023, 5:23:54 PM1/28/23
to objec...@googlegroups.com
Yes, it is not possible to block a thread in JavaScript, AFAIK. When I need flow control I use callbacks—i.e. -runModalWithDidEndBlock:

HTH,

Keary Suska
Esoteritech, Inc.
"Demystifying technology for your home or business”
> --
> You received this message because you are subscribed to the Google Groups "Cappuccino & Objective-J" group.
> To unsubscribe from this group and stop receiving emails from it, send an email to objectivej+...@googlegroups.com.
> To view this discussion on the web visit https://groups.google.com/d/msgid/objectivej/cd1e1b69-c027-439f-9ead-a89f1abf2bben%40googlegroups.com.

Luke

unread,
Jan 29, 2023, 3:38:44 AM1/29/23
to Cappuccino & Objective-J
OK, thanks.  I can live with the callback-based modal design.  

However, the other need I think I have for blocking is that I want to eventually implement server-side storage for my UserDefaults, but the documentation suggests that a -getData callback on the storage manager must be handled synchronously, which sounds difficult if I'm supposed to do a request to a REST server.   It's possible that I figure out how to do a local storage synchronously, but have some other mechanism to sync that store to the server (not implemented in Cappuccino/objj). 

Michael Bach

unread,
Jan 29, 2023, 10:06:21 AM1/29/23
to objec...@googlegroups.com
Dear Luke:

> … However, the other need I think I have for blocking is that I want to eventually implement server-side storage for my UserDefaults, but the documentation suggests that a -getData callback on the storage manager must be handled synchronously, which sounds difficult if I'm supposed to do a request to a REST server. It's possible that I figure out how to do a local storage synchronously, but have some other mechanism to sync that store to the server (not implemented in Cappuccino/objj).

Not sure I understand you correctly, but the mechanism via `CPUserDefaultsController` does not work for you?
Works mostly fine for me – some serialiser, forget which, is buggy, but can be circumvented.

Best, Michael
--
https://michaelbach.de

Keary Suska

unread,
Jan 29, 2023, 1:09:03 PM1/29/23
to objec...@googlegroups.com
Remote server calls can be done synchronously, but it is strongly discouraged. I don’t know what documentation you are looking at, but maybe that’s what they mean. Synchronous server requests are done using XMLHttpRequest (JavaScript native—not Objj/Capp).

HTH,

Keary Suska
Esoteritech, Inc.
"Demystifying technology for your home or business”



> To view this discussion on the web visit https://groups.google.com/d/msgid/objectivej/01579474-363b-4a58-99a6-e10574d606ffn%40googlegroups.com.

Luke

unread,
Feb 1, 2023, 12:43:40 PM2/1/23
to Cappuccino & Objective-J
Thinking about saving the UserDefaults to the server, I had been reading the class comment for CPUserDefaults in the source (on GitHub). 

It says:

CPUserDefaults provides a way of storing a list of user preferences. Everything you store must be CPCoding compliant because it is stored as CPData.

Unlike in Cocoa, CPUserDefaults is per-host by default because of the method of storage. By default, the localStorage API will be used if the browser
supports it. Otherwise a cookie fallback mechanism is utilized. Be aware that if the user erases the local database or clears their cookies, all the
preferences will be lost. Also be aware that this is not a safe storage method; do not store sensitive data in the defaults database.

The storage method utilized is determined by matching the writing domain to a dictionary of stores, concrete subclasses of the CPUserDefaultsStore abstract
class. This is a deviation from Cocoa. You can create a custom defaults store by subclassing the abstract class and implementing the protocol. Currently the
protocol consists of only two methods: -data and -setData:. The latter needs to store the passed in CPData object in your storage mechanism and the former
needs to return an equivalent CPData object synchronously. You can then configure CPUserDefaults to use your storage mechanism using
-setPersistentStoreClass:forDomain:reloadData:


The word "synchronously" got me to thinking about how I'd implement that.

I've put this on the back burner for now though, while I complete the rest of the app.  UserDefaults are working fine with the browser local store for now, but it would be nice if some or all of them could follow the user around, irrespective of the client/browser from which they are currently accessing the app, so I may get back to this later. 

Michael Bach

unread,
Feb 1, 2023, 1:33:23 PM2/1/23
to objec...@googlegroups.com
Dear Luke:

> … UserDefaults are working fine with the browser local store for now,

great

> but it would be nice if some or all of them could follow the user around, irrespective of the client/browser from which they are currently accessing the app, so I may get back to this later.
Ah, yes, that’s quite a different matter, and makes much sense for some scenaris. Sounds rather more involved to me, have no suggestions (am glad that I don’t have that problem :).

Keary Suska

unread,
Feb 1, 2023, 2:45:49 PM2/1/23
to objec...@googlegroups.com
I think the docs there are just warning that the API has a synchronous expectation—i.e. that when -data is called that a meaningful value is immediately returned and when -setData is called that the set data is immediately available to be read. This would be critical for bindings, for instance.

Your best bet would probably be to have a local store and remote store that you keep in sync. Shouldn’t be too bad as long as you have decent failover support for the remote save—i.e. retrying when it fails and having a rollback process that makes sense to the end user. I would overwrite the local store on every launch just to keep things fresh.

HTH,

Keary Suska
Esoteritech, Inc.
"Demystifying technology for your home or business”



> To view this discussion on the web visit https://groups.google.com/d/msgid/objectivej/d66b676e-a9ad-4830-be8e-2dbefc6d5a7bn%40googlegroups.com.

Luke

unread,
Feb 1, 2023, 8:21:20 PM2/1/23
to Cappuccino & Objective-J
Yeah, the same thought had crossed my mind too... make this a 2-phase thing with the server sync'ing being asynchronous and keep the local store synchronous/very fast.
Reply all
Reply to author
Forward
0 new messages