pyftpdlib在文件上缓慢.read阻塞整个mainloop

时间:2011-12-22 03:23:14

标签: python asynchronous ftp asyncore eventlet

Helllo,

我在AbstractFS上使用自定义pyftpdlib,将HTTP服务器上的文件映射到FTP。 这个文件是由openAbstractFS)的实现返回的,该实现返回由以下类包装的httplib.HTTPResponse

class HTTPConnWrapper:
    def __init__(self, obj, filename):
        # make it more file obj like
        self.obj = obj
        self.closed = True
        self.name = filename.split(os.sep)[-1]

    def seek(self, arg):
        pass

    def read(self, bytes):
        #print 'read', bytes
        read = self.obj.read(100) #we DONT read var byes, but 100 bytes
        #print 'ok'
        return read

问题是,如果客户端正在下载文件,则整个服务器都很慢。 我能做什么? 有什么想法吗?

PS: 为什么只用猴子用evenetlet修补所有内容并不会让一切都变得有效?

2 个答案:

答案 0 :(得分:2)

pyftpdlib使用Python的asyncore模块,该模块轮询并与dispatcher进行交互。每次将FTP请求映射到HTTP服务器的请求时,都会阻止pydftpdlib正在使用的asyncore循环。您应该将HTTP请求实现为适合asyncore模型的调度程序,或者生成线程以异步处理请求,并在数据到达时将结果发送回FTP请求处理程序。这有点困难,因为没有提供从外部线程中断asyncore轮询循环的机制。

至于eventlet,我不知道它会与asyncore很好地配合,asyncore已经在使用非阻塞IO机制。

答案 1 :(得分:0)

好的,我在pyftpdlib上发布了bug report

  

我甚至不知道究竟要推荐什么,因为这是一个难以解决的问题,并且没有简单或标准的方法来处理它。

但是我得到了一个疯狂的解决方案来解决这个问题而不使用pyftpdlib。

  1. 使用wsgidav(使用cherrypy)重写所有内容 wsgiserver,所以它的线程)
  2. 将WebDAV文件系统挂载为本机文件系统(net use) windows,mount.davfs在linux上)
  3. 使用任何可以处理的ftp服务器为这个挂载的文件系统提供服务 阻止文件系统