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

  1. variable cmd [Coco new mount $mount lambda {r {
  2. set r [yield]
  3. while {1} {
  4. # this coroutine loops around accepting new requests and resumption requests
  5. set v [dict get? $r -RESUME]
  6. if {$v eq ""} {
  7. # $r is a new request
  8.  
  9. # start an HTTP request
  10. set V [HTTP new http://google.com/ [lambda {v} [string map [list %I [info coroutine] %R [list $r]] {
  11. # augment the original request with the HTTP response,
  12. # in the form of a new request element.
  13. # The Coco coro processes the augmented request, and Resumes
  14. %I [dict merge %R [list -RESUME $v]]
  15. }]] get /]
  16.  
  17. # inform Httpd that we want to suspend this request
  18. set r [yield [Httpd Suspend $r 100000]]
  19. } else {
  20. # $r is a -RESUME request from HTTP, $v is the stuff passed back from HTTP lambda
  21.  
  22. # resume Httpd with the original request,
  23. # but content as delivered from HTTP and transformed here
  24. set result [split [dict get $v -content] \n]
  25. Httpd Resume [Http Ok $r $result text/html]
  26.  
  27. # we may not need to return anything to HTTP lambda (although we can.)
  28. # but we do need to give Httpd a chance to send us new requests
  29. set r [yield]
  30. }
  31. }
  32. }}]

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