Anonymous Monk has asked for the wisdom of the Perl Monks concerning the following question:

Hi folks, a question: I've been thinking about the TV series LOST, and the famous countdown timer (reset whenever someone did something to reset the countdown to the beginning). I was wondering about this for storing some transient data in an array of some kind for non-nefarious purposes, of course. :-)

The data, let's say of the format:

"first name", "last name", "time first entered/renewed"

Where "time first entered/renewed" is the last recorded activity of a person, say in UNIX time (seconds since Jan 1, 1970). Now let's say that a program has created this record and gives the user a expiry of 600 seconds. If there's no activity, remove the entry. If there's activity, reset the timer back to 600s. If there's a new user, create the record and set the countdown on.

Now, how would one do this if there were multiple records of users that were last active at various times? Also, how would one display this info (either interactively or in a dump of the array to file every 30 seconds?

  • Comment on tracking transient data in memory by countdown timer

Replies are listed 'Best First'.
Re: tracking transient data in memory by countdown timer
by BrowserUk (Patriarch) on Feb 21, 2011 at 19:30 UTC

    This sort of thing is trivial with a thread, a queue and some shared variables:

    #! perl -slw use strict; use 5.010; use threads; use threads::shared; use Thread::Queue; sub tprint { my $tid = threads->tid; state $sem :shared; lock $sem; print "$tid: ",@_; } our $PERIOD //= 60; my %db :shared; my $Q = new Thread::Queue; async { while( my( $expiry, $id ) = split ':', $Q->dequeue ) { my $now = time; sleep ( $expiry - $now ) if $now < $expiry; if( $db{ $id } == $expiry ) { lock %db; delete $db{ $id }; tprint "User:$id expired:$expiry; deleted"; } else { tprint "User:$id recently active; reprieved"; } } }->detach; while( sleep 1 ) { my $id = int rand 100; my $expiry = time() + $PERIOD; if( exists $db{ $id } ) { tprint "Existing user:$id active; expiry extended until $expir +y"; } else { tprint "New user:$id added; expiry $expiry"; } lock %db; $db{ $id } = $expiry; $Q->enqueue( "$expiry:$id" ); } __END__ C:\test>889439 -PERIOD=10 0: New user:81 added; expiry 1298316449 0: New user:30 added; expiry 1298316450 0: New user:6 added; expiry 1298316451 0: New user:0 added; expiry 1298316452 0: New user:23 added; expiry 1298316453 0: New user:72 added; expiry 1298316454 0: New user:22 added; expiry 1298316455 0: New user:61 added; expiry 1298316456 0: New user:91 added; expiry 1298316457 0: New user:75 added; expiry 1298316458 1: User:81 expired:1298316449; deleted 0: New user:15 added; expiry 1298316459 1: User:30 expired:1298316450; deleted 0: New user:24 added; expiry 1298316460 1: User:6 expired:1298316451; deleted 0: New user:49 added; expiry 1298316461 1: User:0 expired:1298316452; deleted 0: Existing user:49 active; expiry extended until 1298316462 1: User:23 expired:1298316453; deleted 0: New user:87 added; expiry 1298316463 1: User:72 expired:1298316454; deleted 0: New user:19 added; expiry 1298316464 1: User:22 expired:1298316455; deleted 0: New user:40 added; expiry 1298316465 1: User:61 expired:1298316456; deleted 0: New user:13 added; expiry 1298316466 1: User:91 expired:1298316457; deleted 0: New user:78 added; expiry 1298316467 1: User:75 expired:1298316458; deleted 0: New user:98 added; expiry 1298316468 1: User:15 expired:1298316459; deleted 0: New user:53 added; expiry 1298316469 1: User:24 expired:1298316460; deleted 0: New user:20 added; expiry 1298316470 1: User:49 recently active; reprieved 0: New user:44 added; expiry 1298316471 1: User:49 expired:1298316462; deleted 0: New user:99 added; expiry 1298316472 1: User:87 expired:1298316463; deleted 0: New user:97 added; expiry 1298316473 1: User:19 expired:1298316464; deleted 0: Existing user:20 active; expiry extended until 1298316474 1: User:40 expired:1298316465; deleted 0: New user:24 added; expiry 1298316475 1: User:13 expired:1298316466; deleted 0: New user:70 added; expiry 1298316476 1: User:78 expired:1298316467; deleted 0: New user:87 added; expiry 1298316477 1: User:98 expired:1298316468; deleted 0: New user:42 added; expiry 1298316478 1: User:53 expired:1298316469; deleted 0: New user:79 added; expiry 1298316479 1: User:20 recently active; reprieved 0: New user:56 added; expiry 1298316480 1: User:44 expired:1298316471; deleted 0: New user:48 added; expiry 1298316481 1: User:99 expired:1298316472; deleted 0: Existing user:79 active; expiry extended until 1298316482 1: User:97 expired:1298316473; deleted Terminating on signal SIGINT(2)

    Examine what is said, not who speaks -- Silence betokens consent -- Love the truth but pardon error.
    "Science is about questioning the status quo. Questioning authority".
    In the absence of evidence, opinion is indistinguishable from prejudice.
      Wow! fabulous, this hits the spot. Very illustrative of the concept I was after. Threads? Something else I need to learn about. Again this for this.
Re: tracking transient data in memory by countdown timer
by jethro (Monsignor) on Feb 21, 2011 at 18:28 UTC

    Sort the array of users by last activity time and the next dropout will always be at the start (or end depending on sort order) of the array

    Every second check the first (or last) entry for expiry and update your summary. If you don't mind a small inexactitude, just use sleep(1) to wait a second

Re: tracking transient data in memory by countdown timer
by Eliya (Vicar) on Feb 21, 2011 at 18:15 UTC

    What context are you thinking of?  Web sessions, login sessions (desktop), IRC, ...

      No particular context, I'm thinking in abstracted terms, but, let's try this:

      Data comes in from another program, via a filehandle (could be a socket). The program could be a server, not necessarily a TCP one or UDP one, just a program that gets data.