简体   繁体   中英

Python: No connection could be made because the target machine actively refused it

I having a multi threaded python program, It will continuously open connection with a local URL( http://testing.com/sendMessages_mock.php ), I have installed the WAMP and having sendMessages_mock.php file in local for testing purpose. Sometimes, I get "[Errno 10061] No connection could be made because the target machine actively refused it"

Each thread will call this function. For every one second, there will hundreds of thread calling this function. Getting this exception only for few thread calls. Any thoughts on this ?

def sendMessage(body):
    try:
        request = Request(url="http://testing.com/sendMessages_mock.php", data=json.dumps(body))
        request.add_header('Authorization', 'key=' + CONST.API_KEY)
        request.add_header('Content-Type', 'application/json')
        response = urlopen(request)
        responseData = response.read().decode('utf-8')

    except Exception as exceptionErr:
        print("Oops! " + str(traceback.format_exc()))

If too many calls per second are a problem that causes WAMP to refuse requests and you'd like to solve this on Python side, you could write limiter class which would handle sendMessage execution and limit number of calls.

Mind you this is my first answer to someone else's question, so it might be absolutely wrong. Please have reasonable amount of scepticism.

#python 2.7
import threading

class Throttle(object):
    def __init__(self, call_limit, interval):
        self.call_limit = call_limit
        self.interval = interval
        self.cleaner = None
        self.buffer = threading.Semaphore(call_limit)
        self.calls_in_buffer = 0

    def call(self, function, *args):
        self.buffer.acquire()

        self.calls_in_buffer += 1
        try:
            return function(*args)
        except:
            raise
        finally:
            if self.cleaner == None:
                self._init_cleaner()

    def _drain(self):
        for i in range(self.call_limit):
            self.calls_in_buffer -= 1
            self.buffer.release()
        self.cleaner = None

    def _init_cleaner(self):
        self.cleaner = threading.Timer(self.interval, self._drain)
        self.cleaner.daemon = True
        self.cleaner.start()

Making calls through such class would effectively throttle requests, so server will be able to handle them.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM