Guest User

async threaded http

a guest
Aug 6th, 2015
92
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Nim 2.30 KB | None | 0 0
  1. #Problem: won't work if --boundChecks:on
  2. #Problem is on windows(haven't tested on others) that
  3. #Nim version 0.11.2: compiled --d:release --threads:on --boundChecks:on
  4.  
  5. import asyncdispatch
  6. import rawsockets
  7. import threadpool
  8. import net
  9. import selectors
  10.  
  11. const content = "Hello!"
  12. const response = "HTTP/1.1 200 OK\r\LContent-Length: " & $content.len & "\r\L\r\L" & content
  13.  
  14. type
  15.     ChannelServerWorker = ref object
  16.         SockChan: TChannel[TAsyncFD]
  17.         S: Server
  18.  
  19.     Server = ref object
  20.         Workers: seq[ChannelServerWorker]
  21.         Sockets: seq[TAsyncFD]
  22.         Listener: Socket
  23.  
  24.  
  25. proc HandleSock(sock: TAsyncFD)=
  26.     let futureRead = sock.recv(1023)
  27.     futureRead.callback = proc() =
  28.         discard sock.send(response)
  29.         closeSocket(sock)
  30.     #echo("sock closed!")
  31.  
  32. proc Idle() =
  33.     #idle so the poll wont complain that nothing is registered!
  34.     var sleepF = sleepAsync(100)
  35.     sleepF.callback = proc() =
  36.      Idle()
  37.    
  38. proc Run(csw: ChannelServerWorker) {.thread.} =
  39.     Idle()
  40.     while true:
  41.         let sockTuple = csw.SockChan.tryRecv()
  42.         if sockTuple.dataAvailable:
  43.             let sock = sockTuple.msg
  44.             register(sock)
  45.             sock.HandleSock()
  46.         poll(1)
  47.  
  48. proc NewServer():Server =
  49.     var server = Server()
  50.     server.Workers = @[]
  51.     server.Sockets = @[]
  52.     server.Listener = newSocket()
  53.     return server
  54.  
  55. proc Run(server: Server, numCores:int=4) =
  56.     var threads = newSeq[TThread[ChannelServerWorker]](numCores)
  57.     #Start the threads:
  58.     for t in threads.mitems:
  59.         var csw = ChannelServerWorker()
  60.         csw.S = server
  61.         csw.SockChan.open()
  62.         server.Workers.add(csw)
  63.         t.createThread Run, csw
  64.  
  65.     server.Listener.bindAddr(Port(80), "127.0.0.1")
  66.     server.Listener.listen()
  67.  
  68.     #Loop forever, accept new sock for every worker
  69.     var selector = newSelector()
  70.  
  71.     discard selector.register(server.Listener.getFD(), {EvRead}, nil)
  72.  
  73.     while true:
  74.         for worker in server.Workers:
  75.           if selector.select(1000).len > 0:
  76.               var client: Socket = newSocket()
  77.               accept(server.Listener, client)
  78.               client.getFd().setBlocking(false)
  79.               worker.SockChan.send(client.getFd().TAsyncFD)
  80.  
  81.  
  82. var server = NewServer()
  83. server.Run(4)
Advertisement
Add Comment
Please, Sign In to add comment