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
Bad file descriptor #195
Comments
I did some Googling and it looks like this error occurs when using a socket that has been previously closed. The pymemcached client is designed to close the socket when it gets errors, and to re-open the socket on the next request, and that logic appears to still be there and correct. I did find one place that we could close a socket and fail to re-open it later however:
I suspect that should be something like this instead:
However, in this case, you should still be seeing at least one instance of a different exception before you start seeing errors from sendall. Can you confirm that you are seeing a different exception in the logs before that? Otherwise, it would be helpful to know what methods you are calling on pymemcached and in what order, in case there is a subtle ordering bug in the library. Thank you for the detailed bug report! |
The other error i'm getting is AttributeError 'NoneType' object has no attribute 'sendall'
I'm only using the get and set, but I just realized that i have surrounded the get() with a try catch, and this could be hidding some other errors, i did this because we have a fallback shared cache using redis def memcached_get(self, key):
try:
return self.memcache.get(key)
except:
return None def memcached_set(self, key, value, timeout=MEMCACHED_TIMEOUT):
self.memcache.set(key, value, timeout=timeout) Basicly the way we use the pymemcache is:
|
It would be very helpful to see any errors being thrown in your Just inspecting the code, I can't find a code path that would cause |
My only thought is that For this to be relevant here, |
@G4brym, if you can provide any other details, we should be able to get to the bottom of this. |
Sorry, i wasn't been able to test if there is any error thrown by the get function, i will provide more information tomorrow |
After testing without the try except on the memcache_get, i didn't get any errors on the function, only theses 2 i mentioned on the first post. |
@G4brym are you using gevent or something other than the standard library |
I'm only using this libs |
Is it a single-threaded application? I can see this scenario happening if one client object is used in more than one thread. |
Each server has 5 threads, but memcached is only used locally, per server, so each memcached instance is serving 5 threads only. def build_memcache_conn(self):
if getattr(self, '_memcache_inst', None) is None:
self._memcache_inst = Client(('127.0.0.1', 11211), serializer=json_serializer, deserializer=json_deserializer, connect_timeout=3, timeout=1, ignore_exc=True, no_delay=True)
return self._memcache_inst Each threads call's this function once |
I suggest to do the following trick (it will require you to modify your
If you don't observe a |
I might only give more feedback in 1 or 2 weeks, to test everything and push to production |
any update on this? Error was reported on return sock.recv(size) in _recv function. Sorry I don't have any more detail to give. I had to quickly get the project running. |
@Anakin-Hao Are you running in a multithreaded or concurrent environment? |
I've tried to improve the safety of some of this code in #208, but I haven't uncovered the root cause of the problems noted above. |
@jparise Yes. It's a client used by flask. Threaded. |
@jparise What env did you use to produce the error? Hope that helps. |
We have not been able to reproduce this issue. |
@jparise what's your setup ? |
@Anakin-Hao and @G4brym, would you be able to try the current master code (663ecec) to see if it improves anything? |
@Anakin-Hao and @G4brym, you can also try upgrading to the just-released pymemcache 2.1.0. |
Still happens. Env:
|
@jparise Btw, while reading the code, i noticed there's a flag "use_pooling". I guess you expected no error while use_pooling=False ? |
@Anakin-Hao I suspect your usage of the cache client isn't thread safe. To address that, you would need to protect access to You could also try @1st1's earlier debugging suggestion: #195 (comment) |
@jparise Ok then. Thanks for the effort. |
I am also coming to the conclusion that this is a thread-safety issue. Client objects are not thread safe, so attempting to use the same Client object from multiple threads would definitely cause errors (but I'm not sure exactly what errors, since it would depend on timing/ordering). |
@jparise On a side note, whithout reading the code, is pymemcache designed to leave thread safety to applications? |
Yes, applications are responsible for managing thread safety. There aren't any plans to provide thread safety out of the box. It would require adding a layer of abstracter between the |
I refactored the pymemcache part of my application to comply with thread safety and i haven't seen the error again Thanks for the help |
Closing now that the root cause is understood. |
I have a ton of traffic hitting ~5 servers that connect to the same memcached server.
Memcached config:
pymemcached connector:
The problem is that sometimes i get OSError [Errno 9] Bad file descriptor in the servers.
The code is breaking in
pymemcache/client/base.py in _store_cmd at line 797
And pymemcache/client/base.py in set at line 290
After the error was detected i checked the servers and it still had like 4GB of ram and alot of disk space
I changed the memcache lib from this one to the python-memcached just to test and i didn't have any error, but the response time was slower than when i was using pymemcached.
I'm only opening a connection to the memcache server when the server is starting, maybe it could be that i need to refresh the connection after a while?
Thanks
The text was updated successfully, but these errors were encountered: