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

Server hangs #308

Open
GeorgeCGV opened this issue May 26, 2023 · 2 comments
Open

Server hangs #308

GeorgeCGV opened this issue May 26, 2023 · 2 comments

Comments

@GeorgeCGV
Copy link

GeorgeCGV commented May 26, 2023

I am testing a basic server client example.

The server is done as per the existing example:

class TestRes(aiocoap.resource.ObservableResource):
    async def render_get(self, request):
        return aiocoap.Message(code=aiocoap.numbers.Code.BAD_REQUEST)

root = resource.Site()

root.add_resource(['.well-known', 'core'], resource.WKCResource(root.get_resources_as_linkheader))
root.add_resource(['some','res'], TestRes())

asyncio.Task(aiocoap.Context.create_server_context(bind=(addr,port), site=root))
asyncio.get_event_loop().run_forever()

I place a breakpoint within render_get and invoke a CoAP client that is then terminated while the server is waiting at the breakpoint.

The server code goes into (as it detects that the connection was terminated):

def error_received(self, exception):
    # This is why this whole implementation is a bad idea (but still the best we got on some platforms)
    self.log.warning("Ignoring error because it can not be mapped to any connection: %s", exception)

Unfortunately, the server won't be able to accept any incoming requests from the client anymore. The client goes into constant retransmissions when re-run.

I am not sure why the server is not able to recover... Would appreciate any help.

  • OS: Windows 10
  • Python: 3.8.0
  • aiocoap: 0.4.7
  • asyncio: 3.4.3

python3 -m aiocoap.cli.defaults:

Python version: 3.8.0 (tags/v3.8.0:fa919fd, Oct 14 2019, 19:21:23) [MSC v.1916 32 bit (Intel)]
aiocoap version: 0.4.7
Modules missing for subsystems:
dtls: missing DTLSSocket
oscore: missing cbor2, cryptography, filelock, ge25519
linkheader: everything there
prettyprint: missing cbor2, termcolor, pygments
Python platform: win32
Default server transports: tcpserver:tcpclient:tlsserver:tlsclient:simple6:simplesocketserver
Selected server transports: tcpserver:tcpclient:tlsserver:tlsclient:simple6:simplesocketserver
Default client transports: tcpclient:tlsclient:simple6
Selected client transports: tcpclient:tlsclient:simple6
SO_REUSEPORT available (default, selected): False, False

@chrysn
Copy link
Owner

chrysn commented May 30, 2023

I can't quite reproduce and understand this:

You say the client is terminated while the server is waiting. Later you mention it's not accepting any requests from the client any more. Are you trying again from the same IP address? Same port? (Probably not, as the simple6 transport picks a random port for requests).

The way I've tested it is:

  • Run this server
import aiocoap
from aiocoap import resource
import asyncio

class TestRes(resource.ObservableResource):
    async def render_get(self, request):
        breakpoint()
        return aiocoap.Message(code=aiocoap.numbers.Code.BAD_REQUEST)

root = resource.Site()

root.add_resource(['.well-known', 'core'], resource.WKCResource(root.get_resources_as_linkheader))
root.add_resource(['some','res'], TestRes())

asyncio.Task(aiocoap.Context.create_server_context(bind=('::1', 5683), site=root))
asyncio.get_event_loop().run_forever()

(This is basically your example just with full imports and a concrete loopback address)

  • Run aiocoap-client coap://localhost/some/res
  • Kill the aiocoap-client process while the server is in the breakpoint
  • Continue the server (c)
  • Start the client again: It runs into the breakpoint again.

To test on Linux, I set the AIOCOAP_SERVER_TRANSPORT=tcpserver:tcpclient:tlsserver:tlsclient:simple6:simplesocketserver / AIOCOAP_CLIENT_TRANSPORT=tcpclient:tlsclient:simple6 environment variable to emulate your system's transport choices.

Can you test with these precise commands on Windows, with your full setup on Linux, to tell whether that's a reproducing or a Windows issue?

@GeorgeCGV
Copy link
Author

@chrysn tried with IPv6 (per your example) and with IPv4 (127.0.0.1) using aiocoap-client. Tested on two Win 10 machines one with Python 3.8 and the other with Python 3.11. The same results.

Server code

class TestRes(aiocoap.resource.ObservableResource):
    async def render_get(self, request):
        return aiocoap.Message(code=aiocoap.numbers.Code.BAD_REQUEST)

root = resource.Site()

root.add_resource(['.well-known', 'core'], resource.WKCResource(root.get_resources_as_linkheader))
root.add_resource(['some','res'], TestRes())

asyncio.Task(aiocoap.Context.create_server_context(bind=('::1', 5683), site=root))
asyncio.get_event_loop().run_forever()

Client execution
aiocoap-client coap://localhost:5683/some/res

Steps

  • Start the server, place a breakpoint on return aiocoap.Message(code=aiocoap.numbers.Code.BAD_REQUEST)
  • Start client
  • Terminate the client upon breakpoint hit
  • Resume the server
    • Observe
      Ignoring error because it can not be mapped to any connection: [WinError 1234] No service is operating at the destination network endpoint on the remote system
  • Retry client execution
  • Observe that breakpoint is no longer hit and client outputs (after some time)
    Network error: Retransmissions exceeded

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

2 participants