polycephaly.core.process package¶
-
class
polycephaly.core.process.
Process
(*args, **kwargs)¶ Bases:
polycephaly.core.process.actions.Extend
,polycephaly.core.process.events.Extend
,polycephaly.core.process.info.Extend
,polycephaly.core.process.locking.Extend
,polycephaly.core.process.messaging.Extend
,polycephaly.core.process.setup.Extend
,polycephaly.core.process.signals.Extend
,polycephaly.core.process.threading.Extend
,polycephaly.core.process.timing.Extend
The process class provides the basis for any Process (Main or sub-process) that you want to run.
The overall archiecture is:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21
class Process( polycephaly.core.Process ): def birth( self ): # Set-up is performed here. pass # END METHOD : Birth def life( self ): # Looping is performed here. pass # END METHOD : Life def death( self ): # Tear-down is performed here. pass # END METHOD : Death pass # END CLASS : PROCESS : Main
Arguments and Keyword Arguments are passed in from
Application.addProcess()
whichProcess.__init__()
is responsible for handling.- Parameters
*args – Variable length argument list passed directly to the process, and accessible as
self.args
from within the process.**kwargs – Arbitrary keyword arguments passed directly to the process, and accessible as
self.kwargs
from within the process.
-
__init__
(*args, **kwargs)¶ This is the constructor of the
Process class
, which executes private methods in the following order for helping prepare a process to run:- Parameters
*args – Variable length argument list passed directly to the process, and accessible as
self.args
from within the process.**kwargs – Arbitrary keyword arguments passed directly to the process, and accessible as
self.kwargs
from within the process.
-
_active
= False¶ Boolean whose status is retrieved (and set) by
Process.isActive()
, determines ifProcess.life()
will continue running inProcess.main()
’s loop, and can also be referred to by any child threads that a process spins up (please see Thread Spinner for an example).
-
_application
= None¶ Instance of the
Application class
used byProcess.getApp()
.
-
_callbacks
= None¶ Dictionary of callbacks registered (key is the event name, and value is the callback method) with
Process.registerCallbacks()
that are called byProcess.callbackEvent()
when a specified event occurs.An example use case is when specific USB hardware tracked by a Manufacturer ID and/or Model ID (which Polycephaly matches from all a list of all connected USB devices queried from the Operating System) experiences one or more of the following events:
connected - device plugged in.
disconnected - device unplugged.
pong - responds to a ping sent by a child thread (any method starting with _thread can be automatically launched by
Process.launchThreads()
in theProcess.birth()
method of a process) of a sub-process.commsError - if the device responds to a message with an error letting us know that something went wrong.
deviceError - if the device itself experiences an error.
-
_currFrame
= None¶ Integer used for tracking the progress of frames per second via
Process.currentFrame()
within the span of 1 second for a process’ execution ofProcess.life()
from theProcess.main()
loop.
-
_locks
= None¶ Dictionary of atomic locks for a sub-process to use, which are set by
Process.addLocks()
and queried byProcess.getLocks()
.See also
Process._setupEvents()
is used to setup a lock for each process that’sadded
into an application.
-
_messenger
= None¶ Instance of Polycephaly's Messenger class, and wrapped by methods defined in the process.messaging package.
-
_ppill
= None¶ String (by default, a UUID) that represents a Poison Pill. When a process receives a message with this unique value as the subject line, the process will invoke its
die()
method. Also seeebrake()
which allows any sub-process to request the Main process to shut down the entire application.
-
_ranMailman
= False¶ Boolean that’s used for tracking if
Process.mailman()
was run inProcess.life()
or not. If not, thenProcess.mailman()
will automatically be executed for this cycle and to ensure that thePoison Pill
is received if sent from another process.
-
_runLevel
= None¶ Integer that indicates the process’ current run level (and a poor copy of how Linux does it) which is retrieved (and set) by
Process.runLevel()
-
_runtime
= None¶ Dictionary of a process’ run-time variables, such as frequency, accessible by
getParameter()
.
-
_setupEvents
()¶ Used to setup the process for running. Actions taken:
Sets the process’
active flag
to true.Adds a lock for the process’ message queue, which is most often used by
Process.waitForReply()
.
-
_setupFilters
()¶ Responsible for adding core message filters to be used by all processes:
Main process (determined by
isApplicationMainThread()
)- Emergency Brake - when a process calls
Process.ebrake()
, a message is sent to the Main process requesting that the entire application be shutdown immediately. Callback:
Process.die()
Message parameters:
Subject:
EBRAKE
(case insensitive)
- Emergency Brake - when a process calls
- Process Info - responds to sub-processes asking the Main process for information about other processes.
Callback:
Process.Main.__subProcInfo()
- this method is monkey-patched into the Main process.Message parameters:
Subject:
PROCINFO
(case insensitive)
All processes
- Poison pill - when a process receives this, it will die. To resurrect a dead process,
Application.start()
orApplication.restart()
is needed, which the Main process can access viaProcess.getApp()
. Callback:
Process.die()
Message parameters:
Subject:
Process._ppill
(case insensitive)
- Poison pill - when a process receives this, it will die. To resurrect a dead process,
-
_signalsBak
= None¶ Dictionary used by
Process.backupSignals()
andProcess.restoreSignals()
where key is the name (e.g. SIGINT) and value is the handler (e.g. <built-in function default_int_handler>).
-
_signalsUsed
= False¶ Boolean used by
Process.signalsUsed()
for tracking if any signals have been bound to a callback method withProcess.signals()
.
-
_threads
= None¶ Dictionary of child threads (key is the name, and value is the thread object representing a dedicated method) that a process may spin up. This is used extensively by the methods in the
Process.Threading
package.
-
args
= None¶ Tuple of Arguments that are passed to the sub-process by
Application.addProcess()
.
-
kwargs
= None¶ Dictionary of Keyword Arguments that are passed to the sub-process by
Application.addProcess()
.
-
name
= None¶ String that represents the friendly name of a (sub-)process inheriting from this class.
-
nameMain
= None¶ String that represents the friendly name of the Application’s primary process.
-
paths
= None¶ Object comprised of namespaces representing the various paths used by the application.
-
signalEnd
= None¶ If a Signal is received, an integer representing the Signal event responsible for the shutdown (e.g. 2 for SIGINT, 15 for SIGTERM, etc.). Please note, you can pass this value to
Process.signalsDict()
to obtain the string equivalent.
Submodules¶
polycephaly.core.process.actions module¶
-
class
polycephaly.core.process.actions.
Extend
¶ Bases:
object
-
cleanup
()¶ Used by the Main process during its run of
Process.die()
to send thePoison Pill
to sub-processes thatProcess.activeSubProcesses()
reports as still active.
-
die
(message=None, **kwargs)¶ Commonly used as a callback that can detect internal events (Polycephaly messages) and external events (Signals), this is used by a process to shut itself down.
- Parameters
message (
dict
, optional) – If called by a Polycephaly's Messenger event, this variable will be populated with the message which allows for a reason to explain the shutdown and optionally responding to the sender to confirm the shutdown sequence.**kwargs –
Allows for other events to pass information for shutdown, which can include but are not limited to:
- Signals
sigNum : (
int
, optional) - Signal Integer (e.g. 2 for SIGINT, 15 for SIGTERM, etc.)
- Information
currFrame : (
frame
, optional) - Python stack frame information.reason : (
str
, optional) - why this process is being shutdown.
- Returns
True if successful, False if something went wrong.
- Return type
bool
-
ebrake
(reason=None)¶ Used by a process to request that the entire application be shutdown, which is usually caused by a process encountering an unrecoverable error.
- Parameters
reason (
str
, optional) – Provides an explanation for why a process is requesting that the entire application be shutdown.
-
polycephaly.core.process.events module¶
-
class
polycephaly.core.process.events.
Extend
¶ Bases:
object
-
birth
()¶ This serves as your process’ constructor, and what you would override when you need to prepare your process for starting up.
-
callbackEvent
(event, *args, **kwargs)¶ Attempts to run a callback that was registered to an event with
Process.registerCallbacks()
when a specific event is triggered.- Parameters
event (
str
) – Usually called by a process’ child thread at a specific event, such as (dis)connect or communication/device failure.*args – Passed directly to the callback as arguments.
**kwargs – Passed directly to the callback as keyword arguments.
- Returns
Results directly from the callback.
- Return type
return
An example for triggering an event’s callback:
# System import time # Hardware import myUSBdevice # Polycephaly import polycephaly class Process( polycephaly.core.Process ): def _threadBoardPing( self ): while self.isActive(): # Board successfully responded if myUSBdevice.ping(): self.callbackEvent( 'boardPong', time.time(), abc=123, xyz=789 ) pass # END IF # Device failed to respond else: self.callbackEvent( 'deviceError' ) pass # END ELSE self.freqSleep() pass # END WHILE LOOP pass # END THREAD : Ping USB board def birth( self ): self.launchThreads() pass # END METHOD : Birth pass # END PROCESS
Which would yield:
USB device responded to program ping with pong at 123456.789, abc is 123, and xyz is 789.
-
death
()¶ This serves as your process’ destructor, and what you would override when you need to prepare your process for shutting down.
-
life
()¶ This serves as your process’ loop, and what you would override when you need to setup your process for running n times per second, as defined by the frequency.
-
registerCallbacks
(**kwargs)¶ Used in
Process.birth()
to register events and their reciprocal callbacks. A callback for a specific event is then called byProcess.callbackEvent()
.- Parameters
**kwargs – An arbitrary number of events and their reciprocal callbacks can be passed to this method as keyword arguments.
An example for registering callbacks related to a USB hardware device:
# Polycephaly import polycephaly class Process( polycephaly.core.Process ): def connected( self ): print( 'USB device connected.' ) pass # END METHOD : Connected def disconnected( self ): print( 'USB device disconnected.' ) pass # END METHOD : Disconnected def boardPong( self, time, **kwargs ): print( f"USB device responded to program ping with pong at { time }, abc is { kwargs[ 'abc' ] }, and xyz is { kwargs[ 'xyz' ] }." ) pass # END METHOD : Board pong def commsError( self ): print( 'USB device reports a communications error.' ) pass # END METHOD : Communications Error def deviceError( self ): print( 'USB device is experiencing an error.' ) pass # END METHOD : Device Error def birth( self ): self.registerCallbacks( connected = self.connected, disconnected = self.disconnected, boardPong = self.boardPong, commsError = self.commsError, deviceError = self.deviceError, ) pass # END METHOD : Birth pass # END PROCESS
-
polycephaly.core.process.info module¶
-
class
polycephaly.core.process.info.
Extend
¶ Bases:
object
-
_procInfoSkel
()¶ This is the basis for aliased methods to query the Main process for information about other processes, and is most commonly used by:
- Returns
If process information is found, will return the request, otherwise will return None.
- Return type
return, None
-
activeSubProcesses
()¶ Alias method to show which sub-processes are still active.
- Returns
Sub-processes that are still active.
- Return type
list
-
getApp
()¶ Returns the
Application
instance to a process that’s running in threaded mode.- Returns
If called by a process that’s running in threaded mode, the Application instance will be returned. Otherwise, None will be returned.
- Return type
Application, None
-
getParameter
(name)¶ Used for returning private members of the process, and most commonly used by
Application
to query a process’run-time variables
.- Parameters
name (
str
) – Which private member of the process to return, and the most common use is runtime.- Returns
Value of the private member that’s being looked up.
- Return type
return
-
isActive
(i=None)¶ Used for querying or setting the process’
active flag
. This method is typically used to control the run of process and child-thread loops, including for the loop ofProcess.life()
inProcess.main()
.- Parameters
i (
bool
) – Sets the desired state of the process (and optional child threads).- Returns
The current value of
Process._active
.- Return type
bool
-
listProcessInstances
()¶ Alias method to show process instances.
- Returns
Process instances.
- Return type
list
-
listRecipients
()¶ Alias method to show process message queues.
- Returns
Process message queues.
- Return type
list
-
runLevel
(i=None)¶ Used for querying or setting the process’ run level stored at
Process._runLevel
and within the range defined byProcess.runLevels()
.As a process runs from
Process.birth()
→Process.life()
→Process.death()
, the run level is updated via this method inProcess.main()
.- Parameters
i (
int
orstr
) – Integer value within the defined range (e.g. setting to 1 for indicating BUILDUP level), or a String equivalent (e.g. setting to BUILDUP).- Returns
Run level stored at
Process._runLevel
- Return type
int
- Raises
ValueError – Occurs when
i
is set out of range.
-
runLevels
(i=None)¶ Used for looking up a run level by its integer or string value, or listing all available run levels.
- Parameters
i (
int
orstr
) – Set to the run level to look up, or list to obtain all values.- Returns
String if
i
is set to an integer.Integer if
i
is set to a string.Dictionary if
i
is set to list (str
).
- Return type
str, int, dict
-
polycephaly.core.process.locking module¶
-
class
polycephaly.core.process.locking.
Extend
¶ Bases:
object
-
addLocks
(*args)¶ Adds 1 or more locks to
Process._locks
.- Parameters
*args – Variable length of strings.
-
getLocks
(*args)¶ Retrieves 1 or more locks from
Process._locks
.- Parameters
*args – Variable length of strings.
- Returns
Lock object if a single value is provided, otherwise a dictionary of locks where key is the name and value is the reciprocal lock object.
- Return type
lock, dict
-
polycephaly.core.process.setup module¶
-
class
polycephaly.core.process.setup.
Extend
¶ Bases:
object
-
main
(*args, **kwargs)¶ This method is responsible for the entire run of a process from start to stop, and most notably runs the sequence of:
Process.life()
- runs in a loop so long asProcess.isActive()
evaluates to True.
- Parameters
*args – Variable length argument list passed from process setup.
**kwargs – Arbitrary keyword arguments passed from process setup. Reserved keywords that are used by this argument are:
application (
Application
) - the application instance is the lowest level of the program, which can be accessed from within a process byProcess.getApp()
.
See also
Application.run()
refers to this method for creating the main process.Application._createProcessInstance()
refers to this method for creating sub-processes.
-
polycephaly.core.process.signals module¶
-
class
polycephaly.core.process.signals.
Extend
¶ Bases:
object
-
backupSignals
()¶ Used for backing up signals and their reciprocal handlers as a
dict
toProcess._signalsBak
, where key is the signal name in all capital letters, and value is the handler.See also
-
currSignals
(*args)¶ Used for pulling one or more of the process’ current signal handlers.
- Parameters
*args (
str
) – Signal(s) to retrieve information for.- Returns
If a single argument is given, only a single handler is returned. For multiple arguments given, a dictionary will be returned with the names given and its reciprocal handler.
- Return type
handler or dictionary
-
restoreSignals
()¶ Used for restoring signals and their reciprocal handlers as a
dict
fromProcess._signalsBak
.- Returns
True if successful, False if there are no signals to restore.
- Return type
bool
See also
-
sigTrap
(sigNum, currFrame)¶ This serves as the process’ signal trap for several default signals (e.g. SIGINT and SIGTERM) set in
Process.main()
if you didn’t set any inProcess.birth()
.While you can override this method, you probably won’t ever need to, and can leave this to call upon
Process.die()
, where your process’ specific shutdown actions are carried out inProcess.death()
.- Parameters
sigNum (
int
) – Signal number (e.g. 2 for SIGINT, or 15 for SIGTERM.)currFrame (
frame
) – Python Stack frame.
See also
Process.signalsDict()
- useful for convertingsigNum
to a string representation.
-
signals
(cb, *keys)¶ Bind a callback to an arbitrary number of signals.
- Parameters
cb (
Function
orMethod
) – Callback that’s executed when a signal occurs that it’s been bound to.*keys (
str
) – Variable length list of signals to bind callback to.
- Returns
True if successful, False if an error occurs.
- Return type
bool
An example for registering a callback to multiple signals:
def myCallback( self, sigNum, currFrame ): print( f'My callback received sigNum={ sigNum } and currFrame={ currFrame }' ) pass # END METHOD : My callback def birth( self ): self.signals( self.myCallback, 'SIGINT', # ^C 'SIGTERM', # `kill procID` or `pkill myApp.py` and systemd's default kill signal. ) pass # END METHOD : Birth
See also
-
signalsDict
(k=None)¶ Used for looking up a signal by its integer or string value, or a dictionary listing of all available signals.
- Parameters
k (
int
orstr
, optional)- Returns
Returns a dictionary by default, or the desired signal lookup (string if an integer is given, or integer if a string is given).
- Return type
int
,str
, ordict
-
signalsUsed
(i=None)¶ Used for querying or setting the process’
signals used flag
.- Parameters
i (
bool
, optional) – Value to set the flag to.- Returns
The value of the flag.
- Return type
bool
Note
When
Process.signals()
is called, it uses this method to set the flag to True.
-
polycephaly.core.process.threading module¶
-
class
polycephaly.core.process.threading.
Extend
¶ Bases:
object
-
addChildThread
(name, method, *args, **kwargs)¶ Simplifies creating (and by default, starting) a child thread running under a process with its index created in
Process._threads
.- Parameters
name (
str
) – Name of thread that can be used in conjunction with thread-related methods.method (
method
orfunction
) – Callable that should be run as the thread.*args – Variable length argument list passed directly to the child thread.
**kwargs – Arbitrary keyword arguments passed directly to the child thread.
Please note, there are reserved keywords that are used by this method:
daemon (
bool
, optional, default: True) - Binds thread to process, so when the process exits, the thread does too. You’ll almost always want this turned on.start (
bool
, optional, default: True) - Start the thread after it’s been setup. Otherwise, you can manually start the thread by usinggetChildThread()
to get the instance, and then execute start() on that instance:self.getChildThread( 'hello' ).start()
-
childThreadJanitor
()¶ Automatically removes child threads that are stopped or non-existent, and can be used idempotently in
life()
.
-
getChildThread
(threadName)¶ Obtains a single instance from Process.getChildThreads().
- Parameters
threadName (
str
) – Name of thread to look up.- Returns
If a thread is found,
Thread
is returned, otherwiseNone
is.- Return type
Thread or None
-
getChildThreads
(*args)¶ Obtain child thread instance(s) based on queried names.
- Parameters
*args (
str
) – Variable length argument list of child threads to return from the index located atProcess._threads
.- Returns
Name of the thread
String
as the key, and the value isThread
if found in the index orNone
if not found in the index.- Return type
dict
-
joinChildThreads
()¶ Used in
Process.main()
and run immediately beforeProcess.death()
, this attempts to join each of the process’ child threads that are still active.
-
launchThreads
()¶ Locates any methods in the process whose name begins with _thread_, and then uses
Process.addChildThread()
to add each of these methods as a reciprocal thread, then daemonize and start each thread.An example for automatically launching threads:
def _thread_Hello( self ): while self.isActive(): print( 'Hello' ) self.freqSleep() pass # END WHILE LOOP pass # END METHOD : Hello def _thread_World( self ): while self.isActive(): print( 'World' ) self.freqSleep() pass # END WHILE LOOP pass # END METHOD : World def birth( self ): self.launchThreads() pass # END METHOD : Birth
-
listChildThreadsLives
(*args)¶ Lists status of life for child thread instance(s) based on queried names.
- Parameters
*args (
str
) – Variable length argument list of child threads to return from the index.- Returns
Will return
Boolean
if found in the index, orNone
if not found in the index.- Return type
dict
-
removeChildThreads
(*args)¶ Used for removing stopped child threads from the process’
child threads index
.- Parameters
*args (
str
) – Variable length of stopped child threads to remove from the process.- Returns
Key is the name of the child thread(s) to remove with a value indicating the status of removal from the index:
True - child thread successfully removed.
False - child thread couldn’t be removed since it’s still active.
None - child thread either doesn’t exist or an error was experienced in removing it.
- Return type
dict
-
polycephaly.core.process.timing module¶
-
class
polycephaly.core.process.timing.
Extend
¶ Bases:
object
-
currentFrame
()¶ Returns the current frame within the span of a second from
Process._currFrame
, which is constantly updated inProcess.main()
.For example, if the
Process.frequency()
of this process is 30 and you’re 0.5 seconds into the run, the current frame would be 15.- Returns
The current frame.
- Return type
int
-
currentTimeFrame
()¶ Similar to
Process.currentFrame()
, this method attempts to calculate which frame in a second that the process is operating.- Returns
The current frame.
- Return type
int
-
freqSleep
(multiplier=1)¶ Frequency that should sleep
- Parameters
multiplier (
int
, optional) – Multiplier can be used to extend the sleep time without changing the frequency.Example: if you wanted to double the time, set the value to 2.
-
frequency
(i=None)¶ Sets or queries the frequency of the process.
- Parameters
i (
int
, optional) – Sets the number of times per second that a process should attempt to run.- Returns
Returns the process’ frequency.
- Return type
int
-
lightSleeper
(**kwargs)¶ Sleep timer that can be interrupted by a condition matched against a callback.
- Parameters
**kwargs –
sleep (
int
) - number of seconds to sleep.callback (
Method
orFunction
) - callback that’s evaluated once per second.conditional (
Variable
) - when this variable is different from the callback’s return, then sleep will be interrupted.
- Returns
True if successful sleep, False if woken up early.
- Return type
bool
See also
Thread Spinner in the Examples directory, which makes use of this method in conjunction with
Process.isActive()
.
-