Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Concurrent requests #19

Open
porque0525 opened this issue Dec 28, 2017 · 13 comments
Open

Concurrent requests #19

porque0525 opened this issue Dec 28, 2017 · 13 comments

Comments

@porque0525
Copy link

porque0525 commented Dec 28, 2017

Hi, I'm using uhttpd as a REST server for embedded systems.
I'm planning to use it as a REST server for data centers.
I need to handle concurrent requests or repetitive requests in a second.
I found that the server just knocked down(quited) when the concurrent requests was more than two.
How could I resolve this problem?
Thanks for your great work !!

@fadushin
Copy link
Owner

Duplicates #1

If anyone has some spare cycles to test, contact me. I have some thoughts about how to try.

@mvincm
Copy link

mvincm commented Jan 13, 2018

Hello,

How can I help?

Best regards,
MvincM

@fadushin
Copy link
Owner

Basically with debugging.

I have tried the following:

In ESP (^E, paste, ^D):

class EchoHandler:
   def __init__(self):
       pass

   def handle_request(self, reader, writer, tcp_request):
       import utime
       print("reading line...")
       utime.sleep_ms(10)
       data = yield from reader.readline()
       utime.sleep_ms(10)
       print("got: {}".format(data))
       return True, data

import uhttpd
server = uhttpd.TCPServer(port=80, handler=EchoHandler())
server.run()

On client side (paste into ping.py and make executable):

#!/usr/bin/env python3

import socket
import sys
import time


while True :
    try :
        sock = socket.socket()
        addr = socket.getaddrinfo("192.168.1.200", 80)[0][-1]
        sock.connect(addr)
        n = sock.send("ping {}\n".format(sys.argv[1]).encode())
        print(n)
        ra = sock.recv(4096)
        print(ra)
        time.sleep(0.5)
    except Exception as e :
        print("Caught exception: {}".format(e))
        time.sleep(1)
    finally :
        sock.close()

The server crashes pretty quickly with just two clients running.

I have not been able to get any information about why the ESP is crashing -- and rebooting in the process. Will try screen or something other than minicom, which is clearing the screen on restart.

@fadushin
Copy link
Owner

Sample output:

paste mode; Ctrl-C to cancel, Ctrl-D to finish
=== class EchoHandler:
===    def __init__(self):
===        pass
=== 
===    def handle_request(self, reader, writer, tcp_request):
===        import utime
===        print("reading line...")
===        utime.sleep_ms(10)
===        data = yield from reader.readline()
===        utime.sleep_ms(10)
===        print("got: {}".format(data))
===        return True, data
=== 
=== import uhttpd
=== server = uhttpd.TCPServer(port=80, handler=EchoHandler())
=== server.run()
=== 
loaded sink ulog.console
reading line...
got: b'ping 1\n'
reading line...
got: b'ping 1\n'
reading line...
got: b'ping 1\n'
reading line...
got: b'ping 1\n'
reading line...
got: b'ping 1\n'
reading line...
got: b'ping 1\n'
reading line...
got: b'ping 1\n'
reading line...
got: b'ping 1\n'
reading line...
got: b'ping 2\n'

 ets Jan  8 2013,rst cause:2, boot mode:(3,6)

load 0x40100000, len 31096, room 16 
tail 8
chksum 0x1a
load 0x3ffe8000, len 1076, room 0 
tail 4
chksum 0x56
load 0x3ffe8440, len 3248, room 4 
tail 12
chksum 0x1a
csum 0x1a
lܾ�òà�{nc����$ì��bì$#ì��ÜãÂl�B�$rll�$Ü�|þ2�à�rNb���ll����bì�cä���Â�#ä�$rd��l�ß|þ�rrn#��l�Ü�Û�c�#ä��Üâ���Bì�cl ��Â�ì2�nì�{��n|ä��l��$`��â{�$��ò����l ��Â�o�$ìl���$`��â{�$�¾����ld �s$�o���b��c�"cs��ì�����bìònî��Nnâ���l²�Üd����$��d$�ìd����ì�l��oü�¾�"bll�"����cl��c�rlsdròo�Â���ä���brbìp�bì��b���äì��$bì"ìûNܾ���brìÂ��ß�Ü�à����ìì�pbl`�ì�l�ß|ÿ��{rNb����lÜ��c�Bä���Ü|Û$"l$bd����dnÜl �����lo�prd��l�ß|ÿ�ro#���#5 ets_task(40100130, 3, 3fff837c, 4)
WebREPL daemon started on ws://192.168.4.1:8266
WebREPL daemon started on ws://0.0.0.0:8266
Started webrepl in normal mode

MicroPython v1.9.3-dirty on 2018-01-10; ESP module with ESP8266
Type "help()" for more information.

@mvincm
Copy link

mvincm commented Jan 16, 2018

Ok... so my first test (second test I will do later) was made on:

  • uhttpd server run on virtual machine under windows (not ESP32 !!!)
  • guest system is Linux 4.10.0-42-generic 16.04.1-Ubuntu
  • micropython compilation: MicroPython v1.9.3-238-g42c4dd0 on 2018-01-02; linux version
  • uasyncio release 1.3 (f1fa3a7ff1a5c00be102e5d037fee0d556e4ca17)
  • current version of uhttpd

and.. six parallel clients run for 10 minutes - everything works just fine, no errors or crashes. Now is time for ESP32

@mvincm
Copy link

mvincm commented Jan 17, 2018

Hello,

next part of tests, this time on ESP32.

  • ESP-WROOM-32 - DOIT ESP32 DEVKIT V1 www.doit.am
  • MicroPython: esp32-20180117-v1.9.3-240-ga275cb0f.bin
  • newest uasyncio from official repo
  • newest uhttpd
  • clients on linux
  • the same wifi network

and... 10 parallel clients run form 10 minutes - everything works just fine, no errors or crashes.

So form me... can't reproduce this error... in some free time I will test it on ESP8266.

Best regards,
MvincM

@mvincm
Copy link

mvincm commented Jan 17, 2018

And... I can confirm! On ESP8266 the error/crash could be reproduced. Only one client can work at time. Second will crash system.

Hardware:

  • LoLin new NodeMcu V3
  • micropython: esp8266-20171101-v1.9.3.bin
  • "init.py" from uhttpd pre-compiled to mpy file (in other case there is to low RAM)

So the error is esp8266 specified or to microptyhon version.

Best regards,
MvincM

@fadushin
Copy link
Owner

Excellent thanks for that @mvincm. Still building my ESP32 kit!

We’re you testing above code?

@mvincm
Copy link

mvincm commented Jan 19, 2018

Yeep, I have used yours code form here: issuecomment-357841782

@mvincm
Copy link

mvincm commented Mar 27, 2018

Hello !

Any news? ;)

@mvincm
Copy link

mvincm commented Mar 19, 2019

Hello,

Any news after one year? ;)

M

@fadushin
Copy link
Owner

Sorry, no :(

I have been focused the ESP32, and my time is pretty limited to work on Micropython on the ESP8266. My guess is that there is something fundamental and underlying in either my code, the Micropython code, or the underlying SDK, that is causing issues with concurrent access.

Of course, my personal recommendation is to use Erlang. I have been pretty active in the https://github.com/bettio/AtomVM project, which brings the elegant and beautiful world of Erlang to the ESP community.

Python and concurrency? Abandon hope, all ye who enter here!

@mvincm
Copy link

mvincm commented Mar 26, 2019

Ok, I can understand your situation. I start to write my own http server (as simple as possible but more complex than original micropython example).

BTW... At least Chrome after first request block socket for the future request but do not send anything and these cause problems on micropython http server. It locks socket till timeout (using "uselect.poll" is some solution for single thread http server).

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

3 participants