Modify the main loop in Python's pyxmpp2 to make it high performance _python

Source: Internet
Author: User

Introduction

Before Clubot use of the PYXMPP2 default Mainloop is a poll main loop, but the Clubot after the online resource occupancy is very severe, using strace tracking found Clubot in Non-stop poll, Viewing the PYXMPP2 code found that PYXMPP2 's poll uses a minimum timeout when using timeout blocking, and the minimum timeout is 0, so it becomes a non-blocking poll without timeouts, and does not intend to change the library code. So I wrote a more efficient Epoll Mainloop by imitating poll's mainloop.
Implement

#!/usr/bin/env python #-*-coding:utf-8-*-# author:cold # e-mail:wh_linux@126.com # date:13/01/06 10:41 : # Desc:clubot Epoll mainloop # __future__ Import absolute_import, Division import Select from Pyxmpp2.main  Loop.interfaces import Handlerready, prepareagain from pyxmpp2.mainloop.base import mainloopbase from plugin.util Import
  Get_logger class Epollmainloop (mainloopbase): "" "" "" Main event loop based on the Epoll () syscall on Linux system "" Read_Only = (SELECT. Epollin | Select. Epollpri | Select.
         Epollhup | Select. Epollerr |select. Epollet) Read_write = Read_Only | Select.
    Epollout def __init__ (self, settings = none, handlers= none): Self.epoll = Select.epoll () self._handlers = {} Self._unprepared_handlers = {} Self._timeout = None self._exists_fd = {} Self.logger = Get_logger () Main Loopbase.__init__ (self, settings, handlers) return def _add_io_handler (self, handler): Self._unprepared_handle Rs[hAndler] = None Self._configure_io_handler (handler) def _configure_io_handler (self, handler): If Self.check_even
      TS (): Return if handler in Self._unprepared_handlers:old_fileno = Self._unprepared_handlers[handler] Prepared = Self._prepare_io_handler (handler) Else:old_fileno = None prepared = True Fileno = handle R.fileno () If Old_fileno are not None and Fileno!= Old_fileno:del Self._handlers[old_fileno] Self._exists . Pop (Old_fileno, None) self.epoll.unregister (Old_fileno) if not prepared:self._unprepared_handlers[handle R] = Fileno if not fileno:return self._handlers[fileno] = Handler events = 0 if Handler.is_readab Le (): Events |= self. Read_Only if Handler.is_writable (): Events |= self.
        Read_write if Events:if Fileno in Self._exists_fd:self.epoll.modify (Fileno, events) Else: Self._exists_fd.update ({fileno:1}) SELF.EPOLL.REgister (Fileno, events) def _prepare_io_handler (self, handler): ret = Handler.prepare () if Isinstance (ret, Hand
      Lerready): del Self._unprepared_handlers[handler] prepared = True elif isinstance (ret, Prepareagain): If Ret.timeout is not none:if self._timeout isn't none:self._timeout = min (self._timeout, Ret.timeo  UT) else:self._timeout = ret.timeout prepared = False else:raise typeerror ("unexpected result from Prepare () ") return prepared Def _remove_io_handler (self, handler): if handler in self._unprepared
      _handlers:old_fileno = Self._unprepared_handlers[handler] del Self._unprepared_handlers[handler] Else:
        Old_fileno = Handler.fileno () If Old_fileno is not None:try:del Self._handlers[old_fileno] Self._exists.pop (Old_fileno, None) self.epoll.unregister (Old_fileno) except Keyerror:pass def l Oop_iteration (Self, Timeout = m): next_timeout, sources_handled = Self._call_timeout_handlers () if Self.check_events (): Return If Self._quit:return sources_handled for handler in list (self._unprepared_handlers): Self._configure_io_h Andler (handler) if self._timeout isn't none:timeout = min (timeout, self._timeout) if Next_timeout is not N one:timeout = min (next_timeout, timeout) if timeout = = 0:timeout = 1 # with a timeout of non-blocking, termination resources events = Sel F.epoll.poll (timeout) for FD, flag in Events:if flag & (SELECT. Epollin | Select. Epollpri | Select. Epollet): Self._handlers[fd].handle_read () If Flag & (SELECT. Epollout|select. Epollet): Self._handlers[fd].handle_write () If Flag & (SELECT. Epollerr | Select. Epollet): Self._handlers[fd].handle_err () If Flag & (SELECT. Epollhup | Select. Epollet): Self._handlers[fd].handle_hup () #if flag & Select. Epollnval: #self. _handleRs[fd].handle_nval () sources_handled + + 1 Self._configure_io_handler (SELF._HANDLERS[FD]) return Sources_

 Handled

Use

How do I use the new mainloop? Just pass in the instantiation of the client

Mainloop = Epollmainloop (settings)
client = Client (My_jid, [Self, version_provider], settings, Mainloop)

This will use Epoll as Mainloop
Attention

Epoll is only supported under Linux

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.