Posted to tcl by colin at Mon May 24 09:43:00 GMT 2010view pretty

variable cmd [Coco new mount $mount lambda {r {
    set r [yield]
    while {1} {
	# this coroutine loops around accepting new requests and resumption requests
	set v [dict get? $r -RESUME]
	if {$v eq ""} {
	    # $r is a new request

	    # start an HTTP request
	    set V [HTTP new http://google.com/ [lambda {v} [string map [list %I [info coroutine] %R [list $r]] {
		# augment the original request with the HTTP response,
		# in the form of a new request element.
		# The Coco coro processes the augmented request, and Resumes
		%I [dict merge %R [list -RESUME $v]]
	    }]] get /]

	    # inform Httpd that we want to suspend this request
	    set r [yield [Httpd Suspend $r 100000]]
	} else {
	    # $r is a -RESUME request from HTTP, $v is the stuff passed back from HTTP lambda

	    # resume Httpd with the original request,
	    # but content as delivered from HTTP and transformed here
	    set result [split [dict get $v -content] \n]
	    Httpd Resume [Http Ok $r $result text/html]

	    # we may not need to return anything to HTTP lambda (although we can.)
	    # but we do need to give Httpd a chance to send us new requests
	    set r [yield]
	}
    }
}}]

Comments

Posted by colin at Mon May 24 09:55:02 GMT 2010 [text] [code]

variable cmd [Coco new mount $mount lambda {r { variable pending 0 variable starting 1 set r [yield] while {$starting || $pending > 0} { set starting 0 ;# one shot at starting # this coroutine loops around accepting new requests and resumption requests set v [dict get? $r -RESUME] if {$v eq ""} { # $r is a new request incr pending # start an HTTP request set V [HTTP new http://google.com/ [lambda {v} [string map [list %I [info coroutine] %R [list $r]] { # augment the original request with the HTTP response, # in the form of a new request element. # The Coco coro processes the augmented request, and Resumes %I [dict merge %R [list -RESUME $v]] }]] get /] # inform Httpd that we want to suspend this request set r [yield [Httpd Suspend $r 100000]] } else { # $r is a -RESUME request from HTTP # $v is the stuff passed back from HTTP callback lambda # transform the content passed in from HTTP callback set result [split [dict get $v -content] \n] # resume Httpd with the original request, # but content as delivered from HTTP and transformed here Httpd Resume [Http Ok $r $result text/html] incr pending -1 set forHTTP "" # we may not need to return anything to HTTP lambda (although we can.) # but we do need to give Httpd a chance to send us new requests if {$panding} { set r [yield $forHTTP] } else { # or could just return if we want the Coco to be a one-shot return $forHTTP } } } }}]