Search code examples
pythonraspberry-pipython-asynciocoap

"OSError: [Errno 24] Too many open files:" with sockets from aiocoap context.request()


Hello i am working on a raspberry PI which is supposed to send continuously data from sensors connected to this PI so here is my script :

import logging
import asyncio
from grovepi import*

import time
import json

from aiocoap import *

logging.basicConfig(level=logging.INFO)

def createMsg( file,value ) :
    f= open(file + "Config.json")
    data = json.load(f)
    f.close()
    data["timestamp"] = str(round(time.time(), 3))
    data["value"] = value
    return json.dumps( data )

async def main():

    #analog
    soundSensorPort=0
    lightSensorPort=1

    #digital
    motionSensorPort=2
    tempSensorPort=2
    ultrasonicSensorPort=5
    pinMode(tempSensorPort, "INPUT")

    while True:
        context = await Context.create_client_context()

        await asyncio.sleep(2)
        [ tempSensorValue, humiditySensorValue ]  = dht(tempSensorPort, 0)
        tempMsg = createMsg( "temperatureSensor", tempSensorValue)
        humidityMsg = createMsg( "humiditySensor", humiditySensorValue)

        payloadTemp = tempMsg.encode('utf-8')
        payloadHumidity = humidityMsg.encode('utf-8')
        requestTemp = Message(code=PUT, payload=payloadTemp)
        requestHumidity = Message(code=PUT, payload=payloadHumidity)

        requestTemp.opt.uri_host = '129.6.60.38'
        requestHumidity.opt.uri_host = '129.6.60.38'

        requestTemp.opt.uri_path = ("other", "sensors","temperature")
        requestHumidity.opt.uri_path = ("other", "sensors","humidity")

        responseTemp = await context.request(requestTemp).response
        responseHumidity = await context.request(requestHumidity).response

        print('Result: %s\n%r'%(responseTemp.code, responseTemp.payload))
        print('Result: %s\n%r'%(responseHumidity.code, responseHumidity.payload))

if __name__ == "__main__":
    asyncio.get_event_loop().run_until_complete(main())

but after maybe 20/25 mins of running i have this error :

File "clientPUT.py", line 84, in <module>
  File "/usr/lib/python3.5/asyncio/base_events.py", line 466, in run_until_complete
  File "/usr/lib/python3.5/asyncio/futures.py", line 293, in result
  File "/usr/lib/python3.5/asyncio/tasks.py", line 239, in _step
  File "clientPUT.py", line 63, in main
  File "clientPUT.py", line 27, in createMsg
OSError: [Errno 24] Too many open files: 'temperatureSensorConfig.json'

This is really weird because i close the file just after reading it and loading it in 'f' so if someone have ay ideas it would be very helpful

EDIT 0 : run sudo ls -l /proc/4223/fd returns :

total 0
lrwx------ 1 root root 64 Jun 20 15:38 0 -> /dev/pts/0
lrwx------ 1 root root 64 Jun 20 15:38 1 -> /dev/pts/0
lrwx------ 1 root root 64 Jun 20 15:39 10 -> socket:[155862]
lrwx------ 1 root root 64 Jun 20 15:39 11 -> socket:[155876]
lrwx------ 1 root root 64 Jun 20 15:39 12 -> socket:[155877]
lrwx------ 1 root root 64 Jun 20 15:39 13 -> socket:[155878]
lrwx------ 1 root root 64 Jun 20 15:39 14 -> socket:[155879]
lrwx------ 1 root root 64 Jun 20 15:39 15 -> socket:[155880]
lrwx------ 1 root root 64 Jun 20 15:39 16 -> socket:[155882]
lrwx------ 1 root root 64 Jun 20 15:39 17 -> socket:[154981]
lrwx------ 1 root root 64 Jun 20 15:39 18 -> socket:[154982]
lrwx------ 1 root root 64 Jun 20 15:39 19 -> socket:[153455]
lrwx------ 1 root root 64 Jun 20 15:38 2 -> /dev/pts/0
lrwx------ 1 root root 64 Jun 20 15:39 20 -> socket:[156950]
lrwx------ 1 root root 64 Jun 20 15:39 21 -> socket:[156951]
lrwx------ 1 root root 64 Jun 20 15:39 22 -> socket:[156952]
lrwx------ 1 root root 64 Jun 20 15:39 23 -> socket:[156953]
lrwx------ 1 root root 64 Jun 20 15:39 24 -> socket:[153456]
lrwx------ 1 root root 64 Jun 20 15:39 25 -> socket:[156954]
lrwx------ 1 root root 64 Jun 20 15:39 26 -> socket:[156955]
lrwx------ 1 root root 64 Jun 20 15:39 27 -> socket:[156956]
lrwx------ 1 root root 64 Jun 20 15:39 28 -> socket:[156957]
lrwx------ 1 root root 64 Jun 20 15:39 29 -> socket:[156958]
lrwx------ 1 root root 64 Jun 20 15:38 3 -> /dev/i2c-1
lrwx------ 1 root root 64 Jun 20 15:39 30 -> socket:[156959]
lrwx------ 1 root root 64 Jun 20 15:39 31 -> socket:[156960]
lrwx------ 1 root root 64 Jun 20 15:39 32 -> socket:[156961]
lrwx------ 1 root root 64 Jun 20 15:39 33 -> socket:[156962]
lrwx------ 1 root root 64 Jun 20 15:39 34 -> socket:[156964]
lrwx------ 1 root root 64 Jun 20 15:39 35 -> socket:[156965]
lrwx------ 1 root root 64 Jun 20 15:39 36 -> socket:[156966]
lrwx------ 1 root root 64 Jun 20 15:39 37 -> socket:[156998]
lrwx------ 1 root root 64 Jun 20 15:39 38 -> socket:[154984]
lrwx------ 1 root root 64 Jun 20 15:39 39 -> socket:[155903]
lrwx------ 1 root root 64 Jun 20 15:38 4 -> anon_inode:[eventpoll]
lrwx------ 1 root root 64 Jun 20 15:39 40 -> socket:[155906]
lrwx------ 1 root root 64 Jun 20 15:39 41 -> socket:[153492]
lrwx------ 1 root root 64 Jun 20 15:39 42 -> socket:[153498]
lrwx------ 1 root root 64 Jun 20 15:39 43 -> socket:[153502]
lrwx------ 1 root root 64 Jun 20 15:39 44 -> socket:[155930]
lrwx------ 1 root root 64 Jun 20 15:39 5 -> socket:[155855]
lrwx------ 1 root root 64 Jun 20 15:39 6 -> socket:[155856]
lrwx------ 1 root root 64 Jun 20 15:38 7 -> socket:[155859]
lrwx------ 1 root root 64 Jun 20 15:39 8 -> socket:[155860]
lrwx------ 1 root root 64 Jun 20 15:39 9 -> socket:[155861]

Solution

  • Given CoAP's nature of working both as a server and a client, an aiocoap Context is prepared to react to packages even when no request is currently active, and persists until it gets shut down using the .shutdown() coroutine. Depending on the platform, that often means creation of at least a server socket per context, which can lead to file descriptor exhaustion when too many are created.

    With very few exceptions, there is no reason why an application should ever create more than one context. As this appears to be a common misunderstanding, the documentation is being updated to make this point more explicit.