In-process Synchronization from ABL (Within PASOE's _mp

Posted by dbeavon on 07-Jan-2019 14:31

Does anyone have suggestions about how I might synchronize multiple ABL sessions that are running within a single PASOE process? 

This is needed because of the way that the CLR bridge allows multiple ABL sessions to interact with the *same* internal CLR appdomain.  In some cases the CLR classes that are being used might not be safe for multi-threading, therefore requiring synchronization of some kind (ie. via critical sections or mutexes).

One possible idea I was playing with was the use of a remote client/server database record.  See:

community.progress.com/.../56505

However, when multiple ABL sessions are interacting with a remote record, and they conflict with each other, then it seems to waste a whole second of time (or multiples of 1 second depending on the number of sessions that are being serialized).  This is far too much time.  I was hoping for delays of only a few milliseconds.

Just to elaborate, the real problem I have while interacting with a single CLR appdomain is not the classes in .Net themselves (their static members are generally thread-safe).   It is the Progress CLR bridge that can be unsafe for multi-threading.  While initializing the bridge (for each ABL session in _mproapsv) there seems to be a small chance that the "initialization" operation will fail, depending on whether there are any other ABL sessions which are attempting to initialize themselves at the same time.

Any ideas would be greatly appreciated.  I am hoping for a solution that operates entirely within the memory of a single MS-agent process.  Unfortunately I don't think ABL has any API for doing thread synchronization (or at least nothing that I can find).  Perhaps I could even interact with a local file on disk, since that should not be as slow as locking a remote client/server database record.

All Replies

Posted by Brian K. Maher on 07-Jan-2019 14:38

David,
 
Have you tried find <record> exclusive-lock no-wait no-error followed by checking available(<record>) then pausing using the pause statement (which now supports fractional values like pause 0.25)?
 
Brian Maher
Principal Engineer, Technical Support
Progress
Progress
14 Oak Park | Bedford, MA 01730 | USA
phone
+1 781 280 3075
 
 
Twitter
Facebook
LinkedIn
Google+
 
 

Posted by Matt Baker on 07-Jan-2019 14:49

The overhead of that seems phenomenally high.  Going across a network to get a lock on an object?  Ouch. Wouldn't it be better to use SpinLock object?

docs.microsoft.com/.../system.threading.spinlock

Posted by dbeavon on 07-Jan-2019 14:51

@ Brian : Yes, in the other thread I had mentioned that I was able to eventually use NO-WAIT to make things a bit faster.  

But I'd really like to find a way to do synchronization in-process, and without making use of a remote database.  Using a remote OE database for synchronization of code seems like a very "round-about" approach to solving this problem.  And I really don't want to add more than a few milliseconds of overhead since we use the CLR bridge in our "connect-proc" triggers, and any delays that are introduced there will have a substantial negative impact on clients that are making several round-trips to PASOE at once.

Matt, I could probably use .Net synchronization once I have an initialized CLR bridge to use.   But the errors that I'm facing are happening during the Progress ABL operation which initializes the CLR bridge in the first place.  It's a catch-22 of sorts.  ... I was hoping that the ABL language itself has something I can use for synchronization.  I should note that I have already tried to "preload" the CLR but that doesn't fix the errors - if anything it makes them worse.  I have a case open with Progress tech support but I thought perhaps there may be other ABL programmers who might have found an approach for serializing code that runs within PASOE's MS-Agents.

Posted by Laura Stern on 07-Jan-2019 16:17

I am currently working on the bug about the fact that the CLR Bridge initialization sometimes fails in PASOE.  Generally, there is nothing you will be able to do to fix that because you won't  know what statement it will happen on (or if you use -preloadCLR, your ABL code won't be running at that point).  In any case, maybe you should wait to see if we can figure out why this happening.  

Posted by frank.meulblok on 07-Jan-2019 16:39

[quote user="Laura Stern"]Generally, there is nothing you will be able to do to fix that because you won't  know what statement it will happen on (or if you use -preloadCLR, your ABL code won't be running at that point).[/quote]

I believe you could run without -preloadCLR, then in the session startup procedure add the synchronisation check followed immediately by (a call to something that has) a dummy reference to a .NET class. That first reference should trigger initialization of the .NET bridge, making it a predictable event...

Posted by dbeavon on 07-Jan-2019 17:56

Thanks Laura,  I was preparing to wrap a critical section around the first call to the CLR bridge (which happens in my proc trigger: connect-proc) .  For whatever reason that first use of the CLR seems to be a fairly predictable place for failure.   

I did a limited amount of work to serialize the connect-proc already and it seems to fix the problem. I had attempted my own serialization using OE database record locks.  On the other hand, the remote database interaction also has the effect of simply slowing things down; and we already know that the the problem happens much less frequently when things are running more slowly (eg. it took TS a few tries to reproduce this behavior because of slow VM's, long sleep statements in the reproducible, and because of ABL code that wasn't yet compiled and was being compiled on-the-fly.)

Unless someone has another idea, I might start looking into WIN32 library calls that exclusively lock local files or something like that.  Its not in-process synchronization, but its probably faster than doing remote database operations.

This thread is closed