Beefy Boxes and Bandwidth Generously Provided by pair Networks
good chemistry is complicated,
and a little bit messy -LW
 
PerlMonks  

Re: Duplicate Randoms with SSI

by Rhandom (Curate)
on Oct 26, 2007 at 16:24 UTC ( [id://647429]=note: print w/replies, xml ) Need Help??


in reply to Duplicate Randoms with SSI

Each of those SSI calls will be forking off another process and will have no way to communicate up to the parent process that something has happened.
You do have something else that could potentially work. It has been long enough since I have used an SSI that I don't remember if REMOTE_ADDR, HTTP_REFERER, or REMOTE_USER are set inside of an SSI process - I think that they should be (REMOTE_USER would only be set in an htauthed area). As long as even one of those are set, you can use a solution similar to the following. It isn't 100% accurate - but it should be good enough:
use Cache::Memcached; use Digest::MD5 qw(md5_hex); sub get_random { my ($pick_list, $unique_key) = @_; # add uniqueness to our key $unique_key .= $ENV{'REMOTE_USER'} || $ENV{'REMOTE_ADDR'} # less reliable || $ENV{'HTTP_REFERER'} # least reliable || ''; # based on time now $unique_key = md5_hex($unique_key); # this solution requires a memcache server # or some other cache that handles volitility my $mem = Cache::Memcached->new({servers => ['localhost:11211']}) +; # see what has already been used my $used = $mem->get($unique_key) || []; $used = [] if @$used >= @$pick_list; # reset when full my %used = map {$_ => 1} @$used; my @avail = grep {! $used{$_}} 0 .. $#$pick_list; # pick random item and add it to list of used items my $index = $avail[rand @avail]; push @$used, $index; $mem->set($unique_key, $used); return $pick_list->[$index]; } # use it like this my @items = ("http://foo", "http://bar", "http://baz"); my $page = 'pagefoo'; print get_random(\@items, $page), "\n"; print get_random(\@items, $page), "\n"; print get_random(\@items, $page), "\n"; # it will automatically reset print "Reset\n"; print get_random(\@items, $page), "\n"; print get_random(\@items, $page), "\n"; print get_random(\@items, $page), "\n"; __END__ Prints something like: http://bar http://baz http://foo Reset http://baz http://foo http://bar
You should note that I have used memcached here. My reasoning for doing it is you can have a small localized chunk of memory allocated for this very temporary, very dynamic system and you can insert entries into memcache and then forget about them. The old entries and unused entries are automatically dropped as new entries use up the available memcache space. I would say that for the use you have mentioned here, having a memcache daemon running with only 1MB of allocation would be sufficient for what you are doing.

Oh - and this solution should add very little overhead to your process.
my @a=qw(random brilliant braindead); print $a[rand(@a)];

Log In?
Username:
Password:

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

How do I use this?Last hourOther CB clients
Other Users?
Others sharing their wisdom with the Monastery: (3)
As of 2024-04-19 20:43 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found