mirror of
https://github.com/evennia/evennia.git
synced 2026-04-02 14:07:16 +02:00
Updated ReST documentation.
This commit is contained in:
parent
110207fd7f
commit
85952f8075
23 changed files with 371 additions and 432 deletions
|
|
@ -1,8 +1,7 @@
|
|||
Asynchronous code
|
||||
=================
|
||||
|
||||
*This is considered an advanced topic, probably not useful for most
|
||||
users.*
|
||||
*This is considered an advanced topic.*
|
||||
|
||||
Synchronous versus Asynchronous
|
||||
-------------------------------
|
||||
|
|
@ -68,9 +67,7 @@ call to try to deal with the result from ``long_running_function`` above
|
|||
for processing any data from the function. Instead one has to use
|
||||
*callbacks*.
|
||||
|
||||
``utils.run_async`` takes two optional arguments, ``at_return`` and
|
||||
``at_err``. Both of these should be function defitions. Each will be
|
||||
called automatically.
|
||||
``utils.run_async`` takes reserved arguments.
|
||||
|
||||
- ``at_return(r)`` (the *callback*) is called when the asynchronous
|
||||
function (``long_running_function`` above) finishes successfully. The
|
||||
|
|
@ -82,6 +79,8 @@ called automatically.
|
|||
def at_return(r):
|
||||
print r
|
||||
|
||||
- ``at_return_kwargs`` - an optional dictionary that will be fed as
|
||||
keyword arguments to the ``at_return`` callback.
|
||||
- ``at_err(e)`` (the *errback*) is called if the asynchronous function
|
||||
fails and raises an exception. This exception is passed to the
|
||||
errback wrapped in a *Failure* object ``e``. If you do not supply an
|
||||
|
|
@ -94,6 +93,9 @@ called automatically.
|
|||
def at_err(e):
|
||||
print "There was an error:", str(e)
|
||||
|
||||
- ``at_err_kwargs`` - an optional dictionary that will be fed as
|
||||
keyword arguments to the ``at_err`` errback.
|
||||
|
||||
An example of making an asynchronous call from inside a
|
||||
`Command <Commands.html>`_ definition:
|
||||
|
||||
|
|
@ -126,6 +128,83 @@ and go on with what else need to be done. *Whenever* it finishes, the
|
|||
``at_return`` function will be called and the final value will pop up
|
||||
for us to see. If not we will see an error message.
|
||||
|
||||
Process Pool
|
||||
------------
|
||||
|
||||
The ``ProcPool`` is an Evennia subsystem that launches a pool of
|
||||
processes based on the `ampoule <https://launchpad.net/ampoule>`_
|
||||
package (included with Evennia). When active, ``run_async`` will use
|
||||
this pool to offload its commands. ``ProcPool`` is deactivated by
|
||||
default, it can be turned on with ``settings.PROCPOOL_ENABLED``. *It
|
||||
should be noted that the default SQLite3 database is not suitable for
|
||||
for multiprocess operation. So if you use ``ProcPool`` you should
|
||||
consider switching to another database such as MySQL or PostgreSQL.*
|
||||
|
||||
The Process Pool makes several additional options available to
|
||||
``run_async``.
|
||||
|
||||
The following keyword arguments make sense when ``ProcPool`` is active:
|
||||
|
||||
- ``use_thread`` - this force-reverts back to thread operation (as
|
||||
above). It effectively deactivates all additional features
|
||||
``ProcPool`` offers.
|
||||
- ``proc_timeout`` - this enforces a timeout for the running process in
|
||||
seconds; after this time the process will be killed.
|
||||
- ``at_return``, ``at_err`` - these work the same as above.
|
||||
|
||||
In addition to feeding a single callable to ``run_async``, the first
|
||||
argument may also be a source string. This is a piece of python source
|
||||
code that will be executed in a subprocess via ``ProcPool``. Any extra
|
||||
keyword arguments to ``run_async`` that are not one of the reserved ones
|
||||
will be used to specify what will be available in the execution
|
||||
environment.
|
||||
|
||||
There is one special variable used in the remove execution: ``_return``.
|
||||
This is a function, and all data fed to ``_return`` will be returned
|
||||
from the execution environment and appear as input to your ``at_return``
|
||||
callback (if it is defined). You can call ``_return`` multiple times in
|
||||
your code - the return value will then be a list.
|
||||
|
||||
Example:
|
||||
|
||||
::
|
||||
|
||||
from src.utils.utils import run_async
|
||||
|
||||
source = """
|
||||
from time import sleep
|
||||
sleep(5) # sleep five secs
|
||||
val = testvar + 5
|
||||
_return(val)
|
||||
_return(val + 5)
|
||||
"""
|
||||
|
||||
# we assume myobj is a character retrieved earlier
|
||||
# these callbacks will just print results/errors
|
||||
def callback(ret):
|
||||
myobj.msg(ret)
|
||||
def errback(err):
|
||||
myobj.msg(err)
|
||||
testvar = 3
|
||||
|
||||
# run async
|
||||
run_async(source, at_return=callback, at_err=errback, testvar=testvar)
|
||||
|
||||
# this will return '[8, 13]'
|
||||
|
||||
You can also test the async mechanism from in-game using the ``@py``
|
||||
command:
|
||||
|
||||
::
|
||||
|
||||
@py from src.utils.utils import run_async;run_async("_return(1+2)",at_return=self.msg)
|
||||
|
||||
Note: The code execution runs without any security checks, so it should
|
||||
not be available to unprivileged users. Try
|
||||
``contrib.evlang.evlang.limited_exec`` for running a more restricted
|
||||
version of Python for untrusted users. This will use ``run_async`` under
|
||||
the hood.
|
||||
|
||||
Assorted notes
|
||||
--------------
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue