Beefy Boxes and Bandwidth Generously Provided by pair Networks
Keep It Simple, Stupid
 
PerlMonks  

Re: Looking for alternative for IPC::Shareable (or increase size)

by jcb (Parson)
on Aug 05, 2020 at 22:35 UTC ( [id://11120380]=note: print w/replies, xml ) Need Help??


in reply to Looking for alternative for IPC::Shareable (or increase size)

I have always used pipe, Storable, fork, and Tk's fileevent mechanism for passing results back to a GUI task from various worker tasks. The tricky bit is that you need two "uplink" pipes: one in nonblocking mode that you can give to Tk and read short text reports, and one in blocking mode that you can use with Storable to pass results back from workers. Pipes work even within the same process, so you should be able to easily do something similar with threads. (With forked children and Tk, you must also take care that the children call CORE::exit rather than Tk::exit, which will cause the parent to exit. If you value your sanity, the forked children do not touch the UI.)

Replies are listed 'Best First'.
Re^2: Looking for alternative for IPC::Shareable (or increase size)
by DomX (Novice) on Aug 06, 2020 at 07:12 UTC
    Dear jcb,

    Storable looks pretty good, BUT: the locking mechanism is unsatisfactory. If more than one child is going to manipulate the array, it following could happen: child A lock_retrive array, change array (!), lock_store array. At position of ! another child B could do the same... This means, I'd have to build my own locking mechanism... (Yes, there can be more than one child at my application. ^^' )
    The other way I see combining it with the hint of "Anonymous Monk": Generating separate name spaces for each child, and tell the parent only the name of the space when done... The actual problem here would be how many stores may I create until I reach any storage limits? (Multiple IPC::Shareables are limited, too...)

    Anyways: It sounds faster than using database, so I surely will consider it. (Especially it seems to be implemented in Perl already.)

      The solution I use is for the child processes to feed array updates back to the master process, which applies them to the array. This has worked for me because the worker processes I have needed thus far have always had fully-defined tasks at the moment they are forked — the only communication needed is to report their results back to the master process.

      I have used this technique to maintain Tk GUI responsiveness while issuing network queries in the background, but the data to scrape is known when the process forks and the child only needs to parse a reply and pass the "important bits" back up.

Re^2: Looking for alternative for IPC::Shareable (or increase size)
by DomX (Novice) on Aug 06, 2020 at 11:41 UTC
    So, I tested Storable and my result is unsatisfactory! :'-(
    It also stops at 2^16 characters. And more: It doesn't even tell you about the lost data as IPC::Shareable does...
    If I'm going to split it, I don't need another module. Anyway thank you very much! Going to use special solution for special case: via database.

      That is very strange and I have not had that problem.

      This sounds like you are not properly handling the stored objects. I use a single status pipe, where a child reports some identifier and an indication that a binary object is available, and a "return" pipe for each child, where the Storable data is actually written. The status pipe is non-blocking and monitored with Tk's fileevent mechanism, while the "return" pipes are used in blocking mode. I switched to this approach after trying to pass the Storable data back on the status pipe and finding that non-blocking mode caused problems, not to mention that the status pipe is shared, so the messages returned on it must be kept short enough to fit in the OS buffers to avoid messages from different children being interleaved.

        Hey jcb!

        Bit more details about my structure, and where the problem is:

        - Perl/Tk with Tk::HList showing SQLite database view
        - IPC::Shareable object "transport" for communication with "worker" child
        - fork "worker" (forked before Tk objects become created) communicating with "transport" to Tk.
        - "worker" creates its own IPC::Shareable "ac_trans" for its agents
        -> On Tk's request (Button) the "worker" forks its agents which start doing the actual work.
        - Agents download small bits of data (usually far away from 2^16 characters) and transfer it back to "worker" via "ac_trans".
        - "worker" empties array within "ac_trans" and saves data to a regular array
        - "worker" does this until all agents are exited
        - "worker" fills database with all received data at once (faster than every agent accessing database for one small bit of data)
        - "worker" informs Tk through "transfer" that work is finished.


        Though: one source can't be predicted how many data will be downloaded and here it exceeds the 2^16 characters, IPC::Shareable can't handle, as well as Storeable can't (the way I tested it.).
        So far I already have a database in use, I just create a table and use this for this only case. I think the more wait is worth it on this part. (SQLite supports cells with more than 2 billion characters.) Furthermore the changes are acceptable effort here.

      perhaps have a look at Sys::Mmap and File::Map before using a disk-based DB just because it has locking mechanism.

Log In?
Username:
Password:

What's my password?
Create A New User
Domain Nodelet?
Node Status?
node history
Node Type: note [id://11120380]
help
Chatterbox?
and the web crawler heard nothing...

How do I use this?Last hourOther CB clients
Other Users?
Others cooling their heels in the Monastery: (3)
As of 2024-04-25 07:36 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found