Hello Everyone,

I'm currently developing a basic reverse-proxy that should be running in multi-threaded mode for maximum performance. Yet I'm struggling a bit to make this work. I did simplify the code to make it more readable and shorter..

Can you point me to an example using jester + threads or have a tip for me how to solve it efficiently? Please see the compiler errors in the bottom of this post.

import jester, strtabs, asyncdispatch, os, strutils, json, threadpool
var cpucores = 4
let x: string = "test"
let settings = newSettings(port=Port(5000), staticDir=".", reusePort=true)

proc processLine(line: string) =
  
  routes:
    get "/":
      resp("Hello World!")
    
    get "/json":
      resp("Please use POST-method on this path.")
    
    get "/redirect":
      redirect "http://192.168.0.1:80"
    
    post "/json":
      var push = parseJson($request.body)
      resp ("You have just sent this JSON: " & $push)
    
    post "/redirect":
      var push = parseJson($request.body)
      redirect "http://192.168.0.1:80"
      
      status = Http200
  
  runForever()

var i = 1
while i <= cpucores:
  spawn processLine(x)
  inc(i)
sync()

On compile i get this:

INFO Jester is making jokes at http://localhost:5000
INFO Jester is making jokes at http://localhost:5000
INFO Jester is making jokes at http://localhost:5000
INFO Jester is making jokes at http://localhost:5000
Error: unhandled exception: Address already in use [OSError]
Error: execution of an external program failed: '/root/src2/jester/jester_multi '

I would be very happy to get some help from you experienced nim coders!

Cheers, JohnnyC

2017-12-02 17:40:27
I would be very thankful if someone could help me with an example or advise... 2017-12-03 10:47:08

It's probably best to implement multi-threading at the asynchttpserver-level (for which a PR is forthcoming) instead of jester-level.

It is odd that this doesn't work though. Perhaps reusePort has no effect in Jester.

2017-12-04 10:40:37
Why does this even compile, doesn't look GC safe to me... 2017-12-04 11:41:57
try this, please make shure you use the freshest jester!
import jester  # ./jester/jester # i had to clone the freshest jester
import strtabs, asyncdispatch, os, strutils, json, threadpool
var cpucores = 4
let x: string = "test"
# var settings = newSettings(port=Port(5000), staticDir=".") #,#reusePort = true)

proc processLine(line: string) =
  
  settings:
    port = Port(5000)
    reusePort = true
    appName = "/foo"
    bindAddr = "127.0.0.1"
  
  routes:
    get "/":
      resp("Hello World!")
    
    get "/json":
      resp("Please use POST-method on this path.")
    
    get "/redirect":
      redirect "http://192.168.0.1:80"
    
    post "/json":
      var push = parseJson($request.body)
      resp ("You have just sent this JSON: " & $push)
    
    post "/redirect":
      var push = parseJson($request.body)
      redirect "http://192.168.0.1:80"
      
      status = Http200
  
  runForever()

var i = 1
while i <= cpucores:
  spawn processLine(x)
  inc(i)
sync()
2017-12-04 11:51:21

Wow enthus1ast - This has compiled flawless and is using all cores.

Thanks a lot for the heads up! Will post some performance benchmarks once finished

2017-12-04 12:06:53
JohnnyC i've written some proxys ( nimSocks , upNet [none of wich i claim to be super awesome at the moment, they're toys] ). And also was working on an http proxy (but this unfortunately is stalled for now) maybe we could combine them in a little proxy application which can
  • proxy http, tcp, udp
  • filter/redirect on certain rules etc.
  • possibly has an "reverse connection" protocol

this would be super awesome to have lying around

2017-12-04 15:21:07

enthus1ast: Very interesting indeed. That really sounds like a massive idea! Will hit you up once I'm done with my application and we can see how to merge

Dom69: I'm trying to redirect a HTTP POST (json data) with jester, is that even possible? Or do I need to use httpclient or libcurl to pass the POST-data to the remotehost?

2017-12-04 20:27:55
Well you can read the POST data using this, not sure if this is what you're looking for?
2017-12-06 10:50:43

To redirect a POST, you could use HTTP code 307 (temporary redirect; preserves same http method).

See https://softwareengineering.stackexchange.com/questions/99894/why-doesnt-http-have-post-redirect and https://stackoverflow.com/questions/2068418/whats-the-difference-between-a-302-and-a-307-redirect

post "/..."
    resp Http307, @[("Location", "http://example.com/redirected")], ""

2017-12-06 15:45:36
<<<••12••>>>