# Interact + Mux: how to get independent connections?

**URL:** <https://discourse.julialang.org/t/interact-mux-how-to-get-independent-connections/26538>\
**Category:** Web Stack\
**Created:** [July 19, 2019, 9:44am UTC](https://discourse.julialang.org/t/interact-mux-how-to-get-independent-connections/26538 "2019-07-19T09:44:28Z")\
**Posts on this page:** 3\
**Page:** 1

<div class="post-metadata">

**Author:** ![sylvaticus](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/sylvaticus/32/203883_2.png) [@sylvaticus](https://discourse.julialang.org/u/sylvaticus)\
**Post date:** [July 19, 2019, 9:44am UTC](https://discourse.julialang.org/t/interact-mux-how-to-get-independent-connections/26538/1 "2019-07-19T09:44:28Z")

</div>

Hello, I am trying to get a model whose controls and results are exposed on the web (for now on my own development machine).

I did manage to get a dummy model working, but I noticed that different connections are not independent, i.e. going to [http://localhost:8001](http://localhost:8001) with different browsers I receive starting values of the widgets set by the previous user(s), and the plot getting updated based on the changes made by the other user(s).  
How can I get _independent_ connections ?

This is the toy model I am working with:

```julia
using Interact,Plots,Mux

function myModel(p1,p2,xmin=-50,xmax=50)
    if xmax < xmin
        xmax = xmin
    end
    xrange = collect(xmin:xmax)
    model = p1.*xrange .+ p2.* (xrange) .^2
    return model
end

function createLayout()
  p1s = slider(-20:20, label = "Par#1 (linear term):", value = 1)
  p2s = slider(-5:5, label = "Par#2 (quad term):", value = 1)
  #xmins = slider(0:100, label = "Choose xmin:", value = 0)
  #xmaxs = slider(0:100, label = "Choose xmax:", value = 50)
  mOutput = Interact.@map myModel(&p1s,&p2s)
  plt = Interact.@map plot(collect(-50:50),&mOutput, label="Model output")
  wdg = Widget(["p1" => p1s, "p2" => p2s], output = mOutput)  
  @layout! wdg hbox(plt, vbox(:p1, :p2))
end
myLayout = createLayout()

WebIO.webio_serve(page("/", req -> myLayout), 8001)

```

I don’t know if it is related, I am receiving the following error when exposing the layout trough Mux, although it seems the error is recovered (timeout related?):

```julia
julia> ┌ Error: error handling request
│ exception =
│ IOError: stream is closed or unusable
│ Stacktrace:
│ [1] check_open at ./stream.jl:323 [inlined]
│ [2] uv_write_async(::Sockets.TCPSocket, ::Ptr{UInt8}, ::UInt64) at ./stream.jl:871
│ [3] uv_write(::Sockets.TCPSocket, ::Ptr{UInt8}, ::UInt64) at ./stream.jl:845
│ [4] unsafe_write(::Sockets.TCPSocket, ::Ptr{UInt8}, ::UInt64) at ./stream.jl:901
│ [5] unsafe_write at /home/lobianco/.julia/packages/HTTP/U2ZVp/src/ConnectionPool.jl:134 [inlined]
│ [6] macro expansion at ./gcutils.jl:87 [inlined]
│ [7] write at ./strings/io.jl:165 [inlined]
│ [8] closebody at /home/lobianco/.julia/packages/HTTP/U2ZVp/src/Streams.jl:111 [inlined]
│ [9] closewrite(::HTTP.Streams.Stream{HTTP.Messages.Request,HTTP.ConnectionPool.Transaction{Sockets.TCPSocket}}) at /home/lobianco/.julia/packages/HTTP/U2ZVp/src/Streams.jl:126
│ [10] (::getfield(HTTP.Servers, Symbol("##13#14")){getfield(WebSockets, Symbol("#_servercoroutine#11")){WebSockets.ServerWS},HTTP.ConnectionPool.Transaction{Sockets.TCPSocket},HTTP.Streams.Stream{HTTP.Messages.Request,HTTP.ConnectionPool.Transaction{Sockets.TCPSocket}}})() at ./task.jl:259
└ @ HTTP.Servers ~/.julia/packages/HTTP/U2ZVp/src/Servers.jl:364
Error handling websocket connection:
WebSockets.WebSocketClosedError("ws|server respond to OPCODE_CLOSE 1001:Going Away")
Stacktrace:
 [1] try_yieldto(::typeof(Base.ensure_rescheduled), ::Base.RefValue{Task}) at ./event.jl:196
 [2] wait() at ./event.jl:255
 [3] wait(::Condition) at ./event.jl:46
 [4] wait(::Task) at ./task.jl:188
 [5] create_socket(::Dict{Any,Any}) at /home/lobianco/.julia/packages/WebIO/9qsL8/src/providers/mux.jl:44
 [6] (::getfield(Mux, Symbol("##5#6")){getfield(Mux, Symbol("##28#29")){Array{SubString{String},1}},typeof(WebIO.create_socket)})(::Function, ::Dict{Any,Any}) at /home/lobianco/.julia/packages/Mux/FeATY/src/Mux.jl:17
 [7] #1 at /home/lobianco/.julia/packages/Mux/FeATY/src/Mux.jl:10 [inlined]
 [8] splitquery(::getfield(Mux, Symbol("##1#2")){getfield(Mux, Symbol("##5#6")){getfield(Mux, Symbol("##28#29")){Array{SubString{String},1}},typeof(WebIO.create_socket)},getfield(Mux, Symbol("##1#2")){typeof(Mux.wclose),getfield(Mux, Symbol("##1#2")){getfield(Mux, Symbol("##18#19")){getfield(Mux, Symbol("##22#23")){Symbol,Int64}},getfield(Mux, Symbol("##20#21")){String}}}}, ::Dict{Any,Any}) at /home/lobianco/.julia/packages/Mux/FeATY/src/basics.jl:34
 [9] #1 at /home/lobianco/.julia/packages/Mux/FeATY/src/Mux.jl:10 [inlined]
 [10] wcatch(::getfield(Mux, Symbol("##1#2")){typeof(Mux.splitquery),getfield(Mux, Symbol("##1#2")){getfield(Mux, Symbol("##5#6")){getfield(Mux, Symbol("##28#29")){Array{SubString{String},1}},typeof(WebIO.create_socket)},getfield(Mux, Symbol("##1#2")){typeof(Mux.wclose),getfield(Mux, Symbol("##1#2")){getfield(Mux, Symbol("##18#19")){getfield(Mux, Symbol("##22#23")){Symbol,Int64}},getfield(Mux, Symbol("##20#21")){String}}}}}, ::Dict{Any,Any}) at /home/lobianco/.julia/packages/Mux/FeATY/src/websockets_integration.jl:12
 [11] todict at /home/lobianco/.julia/packages/Mux/FeATY/src/Mux.jl:10 [inlined]
 [12] #3 at /home/lobianco/.julia/packages/Mux/FeATY/src/Mux.jl:14 [inlined] (repeats 2 times)
 [13] (::getfield(Mux, Symbol("##1#2")){getfield(Mux, Symbol("##3#4")){getfield(Mux, Symbol("##3#4")){typeof(Mux.todict),typeof(Mux.wcatch)},typeof(Mux.splitquery)},getfield(Mux, Symbol("##1#2")){getfield(Mux, Symbol("##5#6")){getfield(Mux, Symbol("##28#29")){Array{SubString{String},1}},typeof(WebIO.create_socket)},getfield(Mux, Symbol("##1#2")){typeof(Mux.wclose),getfield(Mux, Symbol("##1#2")){getfield(Mux, Symbol("##18#19")){getfield(Mux, Symbol("##22#23")){Symbol,Int64}},getfield(Mux, Symbol("##20#21")){String}}}}})(::Tuple{HTTP.Messages.Request,WebSockets.WebSocket{Sockets.TCPSocket}}) at /home/lobianco/.julia/packages/Mux/FeATY/src/Mux.jl:10
 [14] (::getfield(Mux, Symbol("##9#10")){Mux.App})(::HTTP.Messages.Request, ::WebSockets.WebSocket{Sockets.TCPSocket}) at /home/lobianco/.julia/packages/Mux/FeATY/src/server.jl:49
 [15] upgrade(::getfield(Mux, Symbol("##9#10")){Mux.App}, ::HTTP.Streams.Stream{HTTP.Messages.Request,HTTP.ConnectionPool.Transaction{Sockets.TCPSocket}}) at /home/lobianco/.julia/packages/WebSockets/pc4iW/src/HTTP.jl:201
 [16] (::getfield(WebSockets, Symbol("#_servercoroutine#11")){WebSockets.ServerWS})(::HTTP.Streams.Stream{HTTP.Messages.Request,HTTP.ConnectionPool.Transaction{Sockets.TCPSocket}}) at /home/lobianco/.julia/packages/WebSockets/pc4iW/src/HTTP.jl:370
 [17] macro expansion at /home/lobianco/.julia/packages/HTTP/U2ZVp/src/Servers.jl:360 [inlined]
 [18] (::getfield(HTTP.Servers, Symbol("##13#14")){getfield(WebSockets, Symbol("#_servercoroutine#11")){WebSockets.ServerWS},HTTP.ConnectionPool.Transaction{Sockets.TCPSocket},HTTP.Streams.Stream{HTTP.Messages.Request,HTTP.ConnectionPool.Transaction{Sockets.TCPSocket}}})() at ./task.jl:259

```

---

<div class="post-metadata">

**Author:** ![piever](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/piever/32/1815_2.png) [@piever](https://discourse.julialang.org/u/piever)\
**Post date:** [July 19, 2019, 11:27am UTC](https://discourse.julialang.org/t/interact-mux-how-to-get-independent-connections/26538/2 "2019-07-19T11:27:02Z")

</div>

I’m not sure about the timeout error, but to get independent apps you can simply do:

```julia
WebIO.webio_serve(page("/", req -> createLayout()), 8001)

```

rather than

```julia
WebIO.webio_serve(page("/", req -> myLayout), 8001)

```

so that each connection gets independent widgets.

---

<div class="post-metadata">

**Author:** ![sylvaticus](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/sylvaticus/32/203883_2.png) [@sylvaticus](https://discourse.julialang.org/u/sylvaticus)\
**Post date:** [July 19, 2019, 12:05pm UTC](https://discourse.julialang.org/t/interact-mux-how-to-get-independent-connections/26538/3 "2019-07-19T12:05:56Z")

</div>

Thank you, got it.  
Concerning the `IOError`, I think it is related to [https://github.com/JuliaWeb/HTTP.jl/issues/392](https://github.com/JuliaWeb/HTTP.jl/issues/392).

I solved the way it is suggested there:

```julia
function serveLayout(port)
    try
      WebIO.webio_serve(page("/", req -> createLayout()), port)
    catch e
      if isa(e, IOError)
        # sleep and then try again
        sleep(0.1)
        serveLayout(port)
      else
        throw(e)
      end
    end
end

serveLayout(8001)

```
