Posted to tcl by Poor Yorick at Wed Feb 09 14:26:04 GMT 2022view pretty
proc waitforstuff {} {
set elapsed [expr {1000 * entier(rand() * 2)}]
puts [list elapsed is $elapsed]
after $elapsed [list [info coroutine]]
yield
}
proc worker {spec body args} {
coroutine [info cmdcount] apply [list $spec $body] {*}$args
}
proc collect {count callback} {
worker {count callback} {
while {$count > 0} {
lassign [yieldto lindex [list [info coroutine]]] url
puts [list collected $url]
incr count -1
}
puts [list {finished collecting} calling $callback]
{*}$callback
} $count $callback
}
proc done {} {
variable status
puts {Zipped and sent!}
set status 0
}
proc download {dirvar urls callback} {
foreach url $urls {
downloader $dirvar $url $callback
}
}
proc downloader {dir url callback} {
worker {dir url callback} {
puts [list downloading $url]
waitforstuff
set content [list content of $url]
save_file $dir $url $content
{*}$callback $url
} $dir $url $callback
}
proc save_file {dirvar url content} {
namespace upvar [namespace current] $dirvar dir
puts [list saving to dir $dirvar]
dict set dir $url $content
}
proc zip {dirvar callback} {
namespace upvar [namespace current] $dirvar dir
waitforstuff
puts [list zipped contents]
foreach {key value} $dir {
puts [list $key $value]
}
{*}$callback
}
proc mail callback {
waitforstuff
puts [list mailed stuff]
{*}$callback
}
proc main_coro {argv0 argv} {
set dir mydir
set urls {one two three}
set collector [collect [llength $urls] [list zip $dir [list mail done]]]
download $dir $urls $collector
}
after 0 [coroutine main main_coro $argv0 $argv]
vwait status
if 0 {
proc zipnmail {dir urls} {
set downloads [all [lmap url $urls {
[pgeturl $url] then [lambda {dir url http_state} {
save_file $dir $url [dict get $http_state body]
} $dir $url]
}]]
set zip [$downloads then [lambda {dir dontcare} {
then_chain [pexec zip -r pages.zip $dir]
} $dir]]
set email [$zip then [lambda dontcare {
then_chain [pexec blat pages.zip -to someone@somewhere.com]
}]]
$email done [lambda {dontcare} {
tk_messageBox -message "Zipped and sent!"
}]
}
}