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!"
	}]
	}
}