Skip to content

Instantly share code, notes, and snippets.

@smls
Created April 8, 2016 14:54
Show Gist options
  • Save smls/bff79cd0b940ffa395261c9126c7ea0b to your computer and use it in GitHub Desktop.
Save smls/bff79cd0b940ffa395261c9126c7ea0b to your computer and use it in GitHub Desktop.
#!/usr/bin/env perl6
# The problem:
# - A (pure) function "getinfo" which takes an ID and calculates a
# return value based on it.
# - Calculating the return value is expensive, so we want to cache
# it and never calculate it twice for the same ID.
# - The function should be thread-safe, and when called
# simultaneously with *different* IDs the calculations should not
# block each other.
# Implementation:
BEGIN (
my $lock = Lock.new;
my %info;
);
sub getinfo ($id) {
my $promise;
$lock.protect: {
$promise = %info{$id} //= start {
# expensive calculation here
sleep 2; rand
}
}
await $promise
}
# Testing:
await do for 1, 2, 3, 2, 2, 2, 2, 2, 2 {
start { say "$_: ", getinfo $_ }
}
# Output notes:
# - The return values for ID 2 are all the same, proving that the
# caching works.
# - The program only takes 2.x seconds if there are three or more
# CPU cores, which proves that the expensive calculations are
# done in parallel as they should.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment