Skip to content

Commit

Permalink
modified: benchmark/functions_benchmark.jl Improved explanations,
Browse files Browse the repository at this point in the history
                                                dropped dead code densityplot
modified:   benchmark/ws_hts.jl                 Added testing for pre-existing
                                                sockets.
modified:   benchmark/ws_jce.jl                 Added explanation for currently unused 'delay' code
modified:   examples/chat_explore.jl            Added reference to alternative close-down method
  • Loading branch information
hustf committed May 14, 2018
1 parent 5fca921 commit 404b3b6
Show file tree
Hide file tree
Showing 4 changed files with 68 additions and 50 deletions.
76 changes: 36 additions & 40 deletions benchmark/functions_benchmark.jl
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ end


"""
Make and get a reference to the server side of HTS-JCE websocket connection.
Make connection and get a reference to the HTS side of HTS-JCE connection.
Assumes a server is already running.
"""
function get_hts_jce()
Expand Down Expand Up @@ -65,7 +65,7 @@ function get_hts_bce()
hts = Union{WebSocket, String}("")
browser =""
opened, browser = open_a_browser()
# Launch the next browser in line.
# Launch the next browser in line.
if opened
zlog(id, "BCE in, ", browser, " will be connecting to HTS. Getting reference...")
zflush()
Expand All @@ -82,17 +82,18 @@ function get_hts_bce()
return hts, browser
end
"""
Collect n (samples) of serverlatency and clientlatency.
Also calculate derived sizes
serverbandwidth, clientbandwidth, serverspeeds, clientspeed
Starts a new JSE-HTS connection for every evaluation (call).
Send n messages of length messagesize HTS-JCE and back.
-> id, serverlatencies, clientlatencies
Starts and closes a new HTS-JCE connection every function call.
In the terminology of BenchmarkTools, a call is a sample
consisting of n evaluations.
"""
function HTS_JCE(n, messagesize)
id = "HTS_JCE"
zlog(id, "Warming up, compiling")
zflush()
hts = get_hts_jce()
if !isa(hts, WebSocket)
if !isa(hts, WebSocket)
msg = " could not get websocket reference"
clog(id, msg)
error(id * msg)
Expand Down Expand Up @@ -130,16 +131,16 @@ function HTS_JCE(n, messagesize)
end
# We must read from the websocket in order for it to respond to
# a closing message from JCE. It's also nice to yield to the async server
# so it can exit from it's handler.
# so it can exit from it's handler and release the websocket reference.
isopen(hts) && read(hts)
yield()
serverlatencies = receivetimes - sendtimes
clientlatencies = receivereplytimes - replytimes
return id, serverlatencies, clientlatencies
end
"""
Use the next browser in line, starts a new HTS-BCE connection and collects n evaluations.
This is one sample.
Use the next browser in line, start a new HTS-BCE connection and collect n evaluations.
This is one sample.
Returns browser name and vectors with n rows:
# t1 Send 0, receive 0, measure time interval
# t2 Send 0, receive 0 twice, measure time interval
Expand All @@ -152,9 +153,9 @@ function HTS_BCE(n, x)
zflush()
msg = ""
(hts, browser) = get_hts_bce()
if browser == ""
if browser == ""
msg = "Could not find and open more browser types"
elseif !isa(hts, WebSocket)
elseif !isa(hts, WebSocket)
msg = " could not get ws reference from " * browser * " via HTS"
end
if msg != ""
Expand Down Expand Up @@ -213,16 +214,16 @@ function HTS_BCE(n, x)
end

"
Measured time interval vectors [ns] -> client and server speeds, bandwidth [ns/b]
x is message size [b].
Constant message size [b], measured time interval vectors [ns]
-> server and client speeds, server and client bandwidth [ns/b]
"

function serverandclientspeeds(x, serverlatencies, clientlatencies)
serverspeeds = serverlatencies / x
clientspeeds = clientlatencies / x
function serverandclientspeeds(messagesize, serverlatencies, clientlatencies)
serverspeeds = serverlatencies / messagesize
clientspeeds = clientlatencies / messagesize
n = length(serverspeeds)
serverbandwidth = sum(serverlatencies) / (n * x)
clientbandwidth = sum(clientlatencies) / (n * x)
serverbandwidth = sum(serverlatencies) / (n * messagesize)
clientbandwidth = sum(clientlatencies) / (n * messagesize)
serverspeeds, clientspeeds, serverbandwidth, clientbandwidth
end

Expand All @@ -234,20 +235,20 @@ x is message size [b].
function serverandclientspeeds_indirect(x, t1, t2, t3, t4)
# assuming a measured time interval consists of
# t(x) = t0s + t0c + a*x + b*x
# where
# where
# t(x) measured time at the server
# t0s initial serverlatency, for a "zero length" message
# t0s initial serverlatency, for a "zero length" message
# t0c initial clientlatency, for a "zero length" message
# x message length [b]
# a marginal server speed [ns/b]
# b marginal client speed [ns/b]
#
#
#
# t1 = t0s + t0c Send 0, receive 0, measure t1
# t2 = t0s + 2t0c Send 0, receive 0 twice, measure t2
# t3 = t0s + t0c + a*x Send x, receive 0, measure t3
# t4 = t0s + 2t0c + a*x + b*x Send x, receive 0, receive x, measure t4
#
#
# hence,
t0s = 2t1 - t2
t0c = -t1 + t2
Expand All @@ -259,48 +260,43 @@ function serverandclientspeeds_indirect(x, t1, t2, t3, t4)
serverspeeds = t0s / x + a
clientspeeds = t0c / x + b
n = length(serverspeeds)
serverbandwidth = sum(serverspeeds) / n
serverbandwidth = sum(serverspeeds) / n
clientbandwidth = sum(clientspeeds) / n
return serverspeeds, clientspeeds, serverbandwidth, clientbandwidth
end


## Note these shorthand function require input symbols defined at module-level
## (not in a local scope)
## Note that the shorthand plot functions below require input symbols
## that are defined at module-level (not in a local scope)

"Shorthand for generating a time series lineplot in REPL"
"Generate a time series lineplot"
lp(sy::Symbol) = lineplot(collect(1:length(eval(sy))), eval(sy), title = String(sy), width = displaysize(STDOUT)[2]-20, canvas = AsciiCanvas)


"Return multiple time series lineplots with a common title prefix"
"Generate a vector of time series lineplots with a common title prefix"
function lp(symbs::Vector{Symbol}, titleprefix)
map(symbs) do sy
pl = lp(sy)
title!(pl, titleprefix * " " * title(pl))
end
end

"Shorthand for generating an x-y lineplot in REPL"
function lp(syx::Symbol, syy::Symbol)
"Generate an x-y lineplot in REPL"
function lp(syx::Symbol, syy::Symbol)
lpl = lineplot(eval(syx), eval(syy), title = String(syy), width = displaysize(STDOUT)[2]-20, canvas = AsciiCanvas)
xlabel!(lpl, String(syx))
end
"Return multiple x-y lineplots with a common title prefix"

"Generate a vector of x-y lineplots with a common title prefix"
function lp(syxs::Vector{Symbol}, syys::Vector{Symbol}, titleprefix)
map(zip(syxs, syys)) do pair
pl = lp(pair[1], pair[2])
title!(pl, titleprefix * " " * title(pl))
end
end

"Shorthand for generating an x-y scatterplot in REPL"
function sp(syx::Symbol, syy::Symbol)
"Generate an x-y scatterplot"
function sp(syx::Symbol, syy::Symbol)
spl = scatterplot(eval(syx), eval(syy), title = String(syy), width = displaysize(STDOUT)[2]-15, canvas = DotCanvas)
xlabel!(spl, String(syx))
end

"Shorthand for generating a densityplot in REPL"
function dp(syx::Symbol, syy::Symbol)
dpl = densityplot(eval(syx), eval(syy), title = String(syy), color = :red, width = displaysize(STDOUT)[2]-15)
xlabel!(dpl, String(syx))
end
end
10 changes: 10 additions & 0 deletions benchmark/ws_hts.jl
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,16 @@ function acceptholdws(http)
# If the ugrade is successful, just hold the reference and thread
# of execution. Other tasks may do useful things with it.
WebSockets.upgrade(http) do ws
if length(WEBSOCKET) > 0
# unexpected behaviour.
if isclosed(WEBSOCKET[1])
pop!(WEBSOCKET)
else
msg = " A websocket is already open. Not accepting the attempt at opening more."
clog(id, :red, msg);zflush()
return
end
end
push!(WEBSOCKET, ws)
zlog(id, ws);zflush()
t1 = now() + WSMAXTIME
Expand Down
20 changes: 12 additions & 8 deletions benchmark/ws_jce.jl
Original file line number Diff line number Diff line change
Expand Up @@ -20,14 +20,20 @@ const SERVER = "ws://127.0.0.1:$(PORT)"
const CLOSEAFTER = Base.Dates.Second(30)

"""
Opens a client, echoes with optional delay, an integer in milliseconds.
Opens a client, echoes with an optional delay, an integer in milliseconds.
Stores time records for received messages and before sending messages.
Specify delay in milliseconds by sending a message on the websocket:
Specify the delay in milliseconds by sending a message on the websocket:
send(ws_jce, "delay|15")
Echoes any message except "exit" and "delay"
Echoes any message except "exit" and "delay".
At exit or after CLOSEAFTER, sends one message containing two vectors of
timestamps [ns].AbstractTrees
Delays to reading, in the websocket use situation, would be caused by usefully spent
calculation time between reads. However, they may be interpreted by the underlying protocol
as transmission problems and cause large slowdowns. Hence the interest in testing
with delays. A countermeasure for optimizing speed might be to run a websocket
reading function in a parallel, not asyncronous process, putting messages on an internal queue.
At exit or after CLOSEAFTER, this function sends one message containing two vectors of
timestamps [ns].
"""
function echowithdelay_jce()
# This will be run in a worker process. Even so, individual console log
Expand Down Expand Up @@ -56,7 +62,7 @@ function echowithdelay_jce()
end
end
"
Handler for client websocket, defined by echowithdelay
Handler for client websocket, defined by echowithdelay_jce
"
function _jce(ws)
id = "_jce"
Expand Down Expand Up @@ -109,8 +115,6 @@ function _jce(ws)
clog(id, :green, " Exit, close websocket.")
zflush()
# Exiting this function starts a closing handshake
# from this side (HTTP.jl:39). The other side must read in
# in order for this to proceed smoothly.
nothing
end
end # module
Expand Down
12 changes: 10 additions & 2 deletions examples/chat_explore.jl
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ named functions may improve error message readability.
=#


# TODO fix errors and style

# Globals, where used in functions will change the type
global lastreq = 0
Expand Down Expand Up @@ -238,8 +238,14 @@ end
info("Start HTTP server on port $(HTTPPORT)")
litas_newtype = @schedule HTTP.listen(server_def_newtype, "127.0.0.1", UInt16(HTTPPORT))

# TODO replace with improvement from 'close websocket'.
"""
This stops the servers using InterruptExceptions.
"""
function closefromoutside()
# Throwing exceptions can be slow. This function also
# starts a task which seems to not exit and free up
# its memory properly. HTTP.listen offers an alternative
# method. See HTTP.listen > tcpref
if isdefined(:litas_newtype)
@schedule Base.throwto(litas_newtype, InterruptException())
end
Expand All @@ -251,4 +257,6 @@ function closefromoutside()
end
end
end


nothing

0 comments on commit 404b3b6

Please sign in to comment.