Die Applikation ist dabei nie auf die Nase gefallen, ich habe testweise 10 Files mit gleicher File-ID mit á 300 MB gleichzeitig an den Webservice geschickt, alle Files werden dabei ohne Probleme dem File angehängt. Daraus ergibt sich für mich die Frage, was passiert hier? Nach meinem Verständnis müssten doch alle Worker gleichzeitig versuchen, in das File zu schreiben, was aber eigentlich einen Fehler schmeißen sollte, da das File bereits geöffnet wird? Oder stimmt Tornado hier bereits den Zugriff ab, oder aber schreiben alle Worker einfach wirr in das File ?
Zugegeben, Tornado macht regen Gebrauch von Asyncio unter der Haube, wovon ich wenig Praxiserfahrung habe.
Der Code (um o.g. Problem mit dem parallelen Filezugriff zu umgehen habe ich ein lock implementiert. Kannte das bisher nur von threading.Lock() um Zugriffe atomar zu machen):
Code: Alles auswählen
from concurrent import futures
from tornado import web, ioloop, gen, concurrent, locks
class Store:
def __init__(self):
self.executor = futures.ThreadPoolExecutor(max_workers=10)
@concurrent.run_on_executor(executor='executor')
def write(self, id, content):
with open(id, 'ab') as fd:
fd.write(content)
class MainHandler(web.RequestHandler):
def initialize(self):
self.store = Store()
self.lock = locks.Lock()
@gen.coroutine
def put(self, id):
with (yield self.lock.acquire()):
yield self.store.write(id, self.request.body)
def start():
return web.Application([
(r"/(.*)", MainHandler),
])
if __name__ == '__main__':
app = start()
app.listen(8888, max_buffer_size=(300*1024*1024))
ioloop.IOLoop.instance().start()