Python: deferToThread XMLRPC Server - Twisted - Cherrypy?

2024/11/18 21:28:01

This question is related to others I have asked on here, mainly regarding sorting huge sets of data in memory.

Basically this is what I want / have:

Twisted XMLRPC server running. This server keeps several (32) instances of Foo class in memory. Each Foo class contains a list bar (which will contain several million records). There is a service that retrieves data from a database, and passes it to the XMLRPC server. The data is basically a dictionary, with keys corresponding to each Foo instance, and values are a list of dictionaries, like so:

data = {'foo1':[{'k1':'v1', 'k2':'v2'}, {'k1':'v1', 'k2':'v2'}], 'foo2':...}

Each Foo instance is then passed the value corresponding to it's key, and the Foo.bar dictionaries are updated and sorted.

class XMLRPCController(xmlrpc.XMLRPC):def __init__(self):...self.foos = {'foo1':Foo(), 'foo2':Foo(), 'foo3':Foo()}...def update(self, data):for k, v in data:threads.deferToThread(self.foos[k].processData, v)def getData(self, fookey):# return first 10 records of specified Foo.barreturn self.foos[fookey].bar[0:10]class Foo():def __init__(self):bar = []def processData(self, new_bar_data):for record in new_bar_data:# do processing, and add record, then sort# BUNCH OF PROCESSING CODEself.bar.sort(reverse=True)

The problem is that when the update function is called in the XMLRPCController with a lot of records (say 100K +) it stops responding to my getData calls until all 32 Foo instances have completed the process_data method. I thought deferToThread would work, but I think I am misunderstanding where the problem is.

Any suggestions... I am open to using something else, like Cherrypy if it supports this required behavior.


EDIT

@Troy: This is how the reactor is set up

reactor.listenTCP(port_no, server.Site(XMLRPCController)
reactor.run()

As far as GIL, would it be a viable option to change sys.setcheckinterval() value to something smaller, so the lock on the data is released so it can be read?

Answer

The easiest way to get the app to be responsive is to break up the CPU-intensive processing in smaller chunks, while letting the twisted reactor run in between. For example by calling reactor.callLater(0, process_next_chunk) to advance to next chunk. Effectively implementing cooperative multitasking by yourself.

Another way would be to use separate processes to do the work, then you will benefit from multiple cores. Take a look at Ampoule: https://launchpad.net/ampoule It provides an API similar to deferToThread.

https://en.xdnf.cn/q/118628.html

Related Q&A

How do I make a linear gradient with Python Turtle?

Im currently trying to replicate this image: https://i.sstatic.net/fymWE.jpg Im trying to make that gradient in the background but I have zero clue how to do it and theres basically nothing on the inte…

Python - Converting an array to a list causes values to change

>>> import numpy as np >>> a=np.arange(0,2,0.2) >>> a array([ 0. , 0.2, 0.4, 0.6, 0.8, 1. , 1.2, 1.4, 1.6, 1.8]) >>> a=a.tolist() >>> a [0.0, 0.2, …

Understand Python Function [closed]

This question is unlikely to help any future visitors; it is only relevant to a small geographic area, a specific moment in time, or an extraordinarily narrow situation that is not generally applicable…

how to download linkedin (save as pdf option) using python

Image what i want to download.Image is of LinkedIn profile page of my friend i want to click on that save-as-pdf option for many users.can that be downloaded using python code? for different users? o…

My tkinter entry box is printing .!entry instead of what is entered

from tkinter import * def _name_():businessname=entry_bnprint(businessname) edit_bar=Tk() name=Label(edit_bar,text="Name:").grid(row=0) entry_bn=Entry(edit_bar) entry_bn.grid(row=0,column=1) …

How to get an average from a row then make a list out of it [duplicate]

This question already has answers here:Reading a CSV file, calculating averages and printing said averages(2 answers)Closed 6 years ago.If I have a csv data that gives two row values of:years grades 20…

Beautiful soup: Extract everything between two tags when these tags have different ids

Beautiful soup: Extract everything between two tags I have seen a question through the above link where we are getting the information between two tags. Whereas I need to get the information between th…

exceptions.RuntimeError - Object has no attribute errno [closed]

Closed. This question needs details or clarity. It is not currently accepting answers.Want to improve this question? Add details and clarify the problem by editing this post.Closed 6 years ago.Improve…

How can I translate this python function to c++?

I am trying to translate a python function to c++ without success. Can someone help me? The python function receives as input a string S and 2 integers (fragment_size and jump). The aim of this functi…

Reverse PDF imposition

I have an imposed document: there are 4 n A4 pages on the n sheets. I put them into a roller image scanner and receive one 2 n paged PDF document (A3).If, say, n = 3, then Ive got the following seque…