Skip to content

Threading

Trent Monahan edited this page Aug 5, 2014 · 2 revisions

Documentation for centralizedThreading.py by Yoshi2

INTRODUCTION:

centralizedThreading.py provides classes for a simple, and most importantly, centralized creation of threads. The goal is to make creation of threads from inside a plugin easy and to provide methods for interaction between threads and plugins. Last, but not least, it allows the IRC bot to signal all threads so they can be shut down in a clean way when it needs to be restarted or when it or a submodule throws an exception.

The required classes will be imported and set up by commandHandler.py, so there are no requirements for the plugins before the threading methods can be used.

METHOD OF OPERATION:

Every function which is put in a thread has to have an unique name, otherwise an FunctionNameAlreadyExists exception will be thrown. The function is then wrapped in a ThreadTemplate class, and executed using standard methods for Python's threading module.

A duplex pipe (a single pipe which allows sending and receiving of data on both ends) is created for communication. The function will receive one end of the pipe, the user will have limited access (send, recv, poll) to the other end of the pipe through methods provides by ThreadPool (or full access by accessing the dictionary containing the threads and their pipes directly, but you shouldn't do this unless you've got a VERY good reason).

Methods:

self.threading.addThread("thread_name", function)

Creates and executes a new thread using the function. thread_name should be an unique string, you are not allowed to create two threads using the same thread_name; a FunctionNameAlreadyExists exception will be thrown in this case.

self.threading.send("thread_name", obj)

Sends an object to the thread with the name thread_name. obj can be any object, but sending very big objects (32mb and up) can cause issues, according to the Python wiki article about multiprocessing pipes.

self.threading.recv("thread_name")

Retrieves an object from the pipe. It blocks if there is no data to be received. See below for how you can deal with this.

self.threading.poll("thread_name", timeout = 0.1)

This method checks whether the pipe contains any data. It waits for a while before returning True, if there is data, or False, when there isn't. The timeout value is in seconds. By default, it waits for 0.1 seconds at most.

self.threading.sigquitThread("thread_name")

Signals the thread that it should shut down itself as soon as possible, and deletes the thread from the internal thread dictionary. This method has not been fully tested yet, please be cautious and report any bugs to the author.

Template for a thread function:

def threadExample(self, pipe):
    ## This is an example of a function which runs indefinitely 
    ## or until the internal signal flag is set, and sends a message
    ## through the pipe
    while self.signal != True:
      time.sleep(10)         
      # This pipe object also has send(obj), recv() and poll(timeout)
      # Check the following link for some more methods for the pipe:
      # http://docs.python.org/2/library/multiprocessing.html#multiprocessing.Connection
      pipe.send("Hello World! 10 seconds have passed.")

NOTE: The self variable in the threadExample does NOT point to the commandHandler class, as it is the case with chat or time events on the IRC bot. In a thread function, like the one in the example, self points to the internal ThreadTemplate class, so that the function can check the status of the thread.

Please consider that, while the threading module has been proved to work under some conditions, it could cause issues under other conditions. Please report any bugs you encounter! Thank you for using the threading module. :)