fadushin / esp8266

This repository contains source code for the ESP8266.
BSD 2-Clause "Simplified" License
73 stars 22 forks source link

Concurrent requests #19

Open porque0525 opened 6 years ago

porque0525 commented 6 years ago

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 commented 6 years ago

Duplicates https://github.com/fadushin/esp8266/issues/1

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

mvincm commented 6 years ago

Hello,

How can I help?

Best regards, MvincM

fadushin commented 6 years ago

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 commented 6 years ago

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ì$#서ÜãÂlBŽ$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ŒcrlsdròoœÂŒäƒbrbìpbìŽ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 commented 6 years ago

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

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

mvincm commented 6 years ago

Hello,

next part of tests, this time on ESP32.

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 commented 6 years ago

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

Hardware:

So the error is esp8266 specified or to microptyhon version.

Best regards, MvincM

fadushin commented 6 years ago

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

We’re you testing above code?

mvincm commented 6 years ago

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

mvincm commented 6 years ago

Hello !

Any news? ;)

mvincm commented 5 years ago

Hello,

Any news after one year? ;)

M

fadushin commented 5 years ago

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 commented 5 years ago

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).