📄 http-agent.tcl
字号:
error "Http/Client requires a page generator (pgtr_)!" } # XXX # rvInterPage_ should only be set when PagePool/ProxyTrace is # *NOT* used if [info exists rvInterPage_] { return [list [$rvInterPage_ value] [$pgtr_ gen-pageid $id_]] } else { return [$pgtr_ gen-request $id_] }}Http/Client instproc next-request { server pageid } { $self instvar ns_ cache_ nextreq_ if [info exists cache_] { $self send-request $cache_ GET $pageid } else { $self send-request $server GET $pageid } # Prepare for the next request set req [$self gen-request] set pageid $server:[lindex $req 1] set itvl [lindex $req 0] if {$itvl >= 0} { set nextreq_([$server id]) [$ns_ at [expr [$ns_ now] + $itvl] \ "$self next-request $server $pageid"] } ;# otherwise it's the end of the request stream }Http/Client instproc set-cache { cache } { $self instvar cache_ set cache_ $cache}# Assuming everything is setup, this function starts sending requests# Sending a request to $cache, the original page should come from $server## Populate a cache with all available pages# XXX how would we distribute pages spatially when we have a hierarchy # of caches? Or, how would we distribute client requests spatially?# It should be used in single client, single cache and single server case# *ONLY*.Http/Client instproc start-session { cache server } { $self instvar ns_ cache_ simStartTime_ $self instvar simStartTime_ pgtr_ set simStartTime_ [$ns_ now] if [info exists pgtr_] { if {[$pgtr_ get-start-time] > $simStartTime_} { $pgtr_ set-start-time $simStartTime_ } } #puts "Client [$self id] starts request session at [$ns_ now]" set cache_ $cache # The first time invocation we don't send out a request # immediately. Instead, we find out when will the first # request happen, then schedule it using next-request{} # Then every time next-request{} is called later, it # sends out a request and schedule the next. set req [$self gen-request] set pageid $server:[lindex $req 1] set itvl [lindex $req 0] if {$itvl >= 0} { $ns_ at [expr [$ns_ now] + $itvl] \ "$self next-request $server $pageid" } ;# otherwise it's the end of the request stream }# Stop sending further requests, and clean all pending requestsHttp/Client instproc stop-session { server } { $self instvar ns_ nextreq_ pending_ cache_ set sid [$server id] # Clean up all pending requests if [info exists nextreq_($sid)] { $ns_ cancel $nextreq_($sid) } if {![info exists pending_]} { return } # XXX If a client either connects to a *SINGLE* cache # or a *SINGLE* server, then we remove all pending requests # when we are disconnected. if {[info exists cache_] && ($server == $cache_)} { unset pending_ } else { # Only remove pending requests related to $server foreach p [array names pending_] { if {$server == [lindex [split $p :] 0]} { unset pending_($p) } } }}Http/Client instproc populate { cache server } { $self instvar pgtr_ curpage_ status_ ns_ if ![info exists status_] { set status_ "POPULATE" set curpage_ 0 } if [info exists pgtr_] { # Populate cache with all pages incrementally if {$curpage_ < [$pgtr_ get-poolsize]} { $self send-request $cache GET $server:$curpage_ incr curpage_ $ns_ at [expr [$ns_ now] + 1] \ "$self populate $cache $server"# if {$curpage_ % 1000 == 0} {# puts "Client [$self id] populated $curpage_"# } return } } # Start sending requests $ns_ at [expr [$ns_ now] + 10] "$self start-session $cache $server"}Http/Client instproc start { cache server } { $self instvar cache_ set cache_ $cache $self populate $cache $server}Http/Client instproc request-mpush { page } { $self instvar mpush_refresh_ ns_ cache_ $self send $cache_ [$self get-mpusize] \ "$cache_ request-mpush $page" Http/Client instvar hb_interval_ set mpush_refresh_($page) [$ns_ at [expr [$ns_ now] + $hb_interval_] \ "$self send-refresh-mpush $page"]}Http/Client instproc send-refresh-mpush { page } { $self instvar mpush_refresh_ ns_ cache_ $self send $cache_ [$self get-mpusize] "$cache_ refresh-mpush $page" #puts "[$ns_ now]: Client [$self id] send mpush refresh" Http/Client instvar hb_interval_ set mpush_refresh_($page) [$ns_ at [expr [$ns_ now] + $hb_interval_] \ "$self send-refresh-mpush $page"]}# XXX We use explicit teardown. Http/Client instproc stop-mpush { page } { $self instvar mpush_refresh_ ns_ cache_ if [info exists mpush_refresh_($page)] { # Stop sending the periodic refreshment $ns_ cancel $mpush_refresh_($page) #puts "[$ns_ now]: Client [$self id] stops mpush" } else { error "no mpush to cancel!" } # Send explicit message up to tear down $self send $cache_ [$self get-mpusize] "$cache_ stop-mpush $page"}#----------------------------------------------------------------------# Client which is capable of handling compound pages#----------------------------------------------------------------------Class Http/Client/Compound -superclass Http/ClientHttp/Client/Compound instproc set-interobj-generator { ranvar } { $self instvar rvInterObj_ set rvInterObj_ $ranvar}# Generate next page request and the number of embedded objects for # this page. # Use rvInterPage_ to generate interval between pages (inactive OFF), and # use rvInterObj_ to generate interval between embedded objects (active OFF)Http/Client/Compound instproc next-request { server pageid } { # First schedule next page request eval $self next $server $pageid}# Request the next embedded object(s)Http/Client/Compound instproc next-obj { server args } { $self instvar pgtr_ cache_ req_objs_ ns_ rvInterObj_ if ![llength $args] { # No requests to make return } if [info exists cache_] { set dest $cache_ } else { set dest $server } set pageid [lindex $args 0] set mpgid [$pgtr_ get-mainpage $pageid] ;# main page id set max 0 set origsvr [lindex [split $pageid :] 0] foreach pageid $args { set id [lindex [split $pageid :] 1] if {$max < $id} { set max $id } incr req_objs_($mpgid) -1 $self send-request $dest GET $pageid } if {$req_objs_($mpgid) <= 0} { # We have requested all objects for this page, done. return } # Schedule next requests. Assuming we get embedded objects according # to the ascending order of their page id set objid [join [$pgtr_ get-next-objs $origsvr:$max]] puts "At [$ns_ now], client [$self id] get objs $objid" if [info exists rvInterObj_] { $ns_ at [expr [$ns_ now] + [$rvInterObj_ value]] \ "$self next-obj $server $objid" } else { $self next-obj $server $objid }}# XXX We need to override get-response-GET because we need to recompute# the RCV time, and the STA time, etc. # XXX Allow only *ONE* compound page.Http/Client/Compound instproc get-response-GET { server pageid args } { $self instvar pending_ id_ ns_ recv_objs_ max_stale_ stat_ \ simStartTime_ pgtr_ if ![info exists pending_($pageid)] { error "Client $id_: Unrequested response page $pageid from server/cache [$server id]" } # Check if this is the main page if [$pgtr_ is-mainpage $pageid] { set mpgid $pageid # Get all the embedded objects, do "active OFF" delay # if available $self instvar req_objs_ recv_objs_ rvInterObj_ # Objects that are to be received set recv_objs_($pageid) [$pgtr_ get-obj-num $pageid] # Objects that have been requested set req_objs_($pageid) $recv_objs_($pageid) set objid [join [$pgtr_ get-next-objs $pageid]] if [info exists rvInterObj_] { $ns_ at [expr [$ns_ now] + [$rvInterObj_ value]] \ "$self next-obj $server $objid" } else { eval $self next-obj $server $objid } } else { # Main page id set mpgid [$pgtr_ get-mainpage $pageid] } array set data $args # Check stale hits and record maximum stale hit time set origsvr [lindex [split $pageid :] 0] set modtime [$origsvr get-modtime $pageid] set reqtime [lindex $pending_($pageid) 0] set reqrtt [expr [$ns_ now] - $reqtime] # XXX If a stale hit occurs because a page is modified during the RTT # of the request, we should *NOT* consider it a stale hit. We # implement it by ignoring all stale hits whose modification time is # larger than the request time. # # See Http/Client::get-response-GET{} if {$modtime > $data(modtime)} { $self instvar ns_ # Staleness is the time from now to the time it's last modified set tmp [$origsvr stale-time $pageid $data(modtime)] if {$tmp > $reqrtt/2} { if ![info exists max_stale_($mpgid)] { set max_stale_($mpgid) $tmp } elseif {$max_stale_($mpgid) < $tmp} { set max_stale_($mpgid) $tmp } } } # Wait for the embedded objects if this is a main page if [$pgtr_ is-mainpage $pageid] { return } # Delete pending record of all embedded objects, but not the main page; # we need it later to compute the response time, etc. # XXX assuming only one request per object $self evTrace C RCV p $pageid s [$server id] l $reqrtt z $data(size) unset pending_($pageid) # Check if we have any pending embedded objects incr recv_objs_($mpgid) -1 if {$recv_objs_($mpgid) > 0} { # We are waiting for more objects to come return } # Now we've received all objects $self instvar pgtr_ # Record response time for the entire compound page set reqtime [lindex $pending_($mpgid) 0] $self evTrace C RCV p $mpgid s [$origsvr id] l \ [expr [$ns_ now] - $reqtime] z $data(size) # We are done with this page unset pending_($mpgid) if [info exists simStartTime_] { set tmp [expr [$ns_ now] - $reqtime] set stat_(rep-time) [expr $stat_(rep-time) + $tmp] if {$stat_(rt-min) > $tmp} { set stat_(rt-min) $tmp } if {$stat_(rt-max) < $tmp} { set stat_(rt-max) $tmp } unset tmp } if [info exists max_stale_($mpgid)] { $self evTrace C STA p $mpgid s [$origsvr id] \ l $max_stale_($mpgid) if [info exists simStartTime_] { incr stat_(stale-num) set stat_(stale-time) [expr \ $stat_(stale-time) + $max_stale_($mpgid)] if {$stat_(st-min) > $max_stale_($mpgid)} { set stat_(st-min) $max_stale_($mpgid) } if {$stat_(st-max) < $max_stale_($mpgid)} { set stat_(st-max) $max_stale_($mpgid) } } unset max_stale_($mpgid) } $self mark-response $mpgid}Http/Client/Compound instproc mark-request { pageid } { set id [lindex [split $pageid :] end] if {$id == 0} { $self next $pageid }}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -