kore

Kore is a web application platform for writing scalable, concurrent web based processes in C or Python.
Commits | Files | Refs | README | LICENSE | git clone https://git.kore.io/kore.git

commit c74c1f781d73614ae49b7118ec3762ea5a4f1736
parent 8b1a5add4bc4eca3a1c80cc9ce26addd1f6225d8
Author: Joris Vink <joris@coders.se>
Date:   Thu, 22 Nov 2018 15:23:44 +0100

Add python-async example.

Diffstat:
examples/python-async/.gitignore | 6++++++
examples/python-async/README.md | 11+++++++++++
examples/python-async/conf/build.conf | 34++++++++++++++++++++++++++++++++++
examples/python-async/conf/python-async.conf | 21+++++++++++++++++++++
examples/python-async/src/async_lock.py | 38++++++++++++++++++++++++++++++++++++++
examples/python-async/src/async_process.py | 64++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
examples/python-async/src/async_queue.py | 57+++++++++++++++++++++++++++++++++++++++++++++++++++++++++
examples/python-async/src/setup.py | 23+++++++++++++++++++++++
8 files changed, 254 insertions(+), 0 deletions(-)

diff --git a/examples/python-async/.gitignore b/examples/python-async/.gitignore @@ -0,0 +1,6 @@ +*.o +.flavor +.objs +python-async.so +assets.h +cert diff --git a/examples/python-async/README.md b/examples/python-async/README.md @@ -0,0 +1,11 @@ +Kore python async/await examples. + +Run: +``` + $ kodev run +``` + +Test: +``` + $ curl -k https://127.0.0.1:8888/queue +``` diff --git a/examples/python-async/conf/build.conf b/examples/python-async/conf/build.conf @@ -0,0 +1,34 @@ +# python-async build config +# You can switch flavors using: kodev flavor [newflavor] + +# Set to yes if you wish to produce a single binary instead +# of a dynamic library. If you set this to yes you must also +# set kore_source together with kore_flavor. +single_binary=yes +kore_source=../../ +kore_flavor=PYTHON=1 + +# The flags below are shared between flavors +cflags=-Wall -Wmissing-declarations -Wshadow +cflags=-Wstrict-prototypes -Wmissing-prototypes +cflags=-Wpointer-arith -Wcast-qual -Wsign-compare + +cxxflags=-Wall -Wmissing-declarations -Wshadow +cxxflags=-Wpointer-arith -Wcast-qual -Wsign-compare + +# Mime types for assets served via the builtin asset_serve_* +#mime_add=txt:text/plain; charset=utf-8 +#mime_add=png:image/png +#mime_add=html:text/html; charset=utf-8 + +dev { + # These flags are added to the shared ones when + # you build the "dev" flavor. + cflags=-g + cxxflags=-g +} + +#prod { +# You can specify additional flags here which are only +# included if you build with the "prod" flavor. +#} diff --git a/examples/python-async/conf/python-async.conf b/examples/python-async/conf/python-async.conf @@ -0,0 +1,21 @@ +# python-async configuration + +bind 127.0.0.1 8888 + +tls_dhparam dh2048.pem + +python_path src + +python_import ./src/setup.py +python_import ./src/async_lock.py +python_import ./src/async_queue.py +python_import ./src/async_process.py + +domain * { + certfile cert/server.pem + certkey cert/key.pem + + static /queue async_queue + static /lock async_lock + static /proc async_proc +} diff --git a/examples/python-async/src/async_lock.py b/examples/python-async/src/async_lock.py @@ -0,0 +1,38 @@ +# +# Copyright (c) 2018 Joris Vink <joris@coders.se> +# +# Permission to use, copy, modify, and distribute this software for any +# purpose with or without fee is hereby granted, provided that the above +# copyright notice and this permission notice appear in all copies. +# +# THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES +# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF +# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR +# ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES +# WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN +# ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF +# OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. +# + +# +# Locking example. +# +# The handler for /lock will grab the shared lock, suspend itself for +# 5 seconds before releasing the lock and responding. +# +# While the lock is held, other requests to /lock will block until it +# is released. + +import kore + +# The shared lock +lock = kore.lock() + +async def async_lock(req): + # A kore.lock should be used with the "async with" syntax. + async with lock: + # Suspend for 5 seconds. + await kore.suspend(5000) + + # Now respond. + req.response(200, b'') diff --git a/examples/python-async/src/async_process.py b/examples/python-async/src/async_process.py @@ -0,0 +1,64 @@ +# +# Copyright (c) 2018 Joris Vink <joris@coders.se> +# +# Permission to use, copy, modify, and distribute this software for any +# purpose with or without fee is hereby granted, provided that the above +# copyright notice and this permission notice appear in all copies. +# +# THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES +# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF +# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR +# ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES +# WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN +# ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF +# OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. +# + +# +# Asynchronous process example. +# +# Wait for the result of an external process asynchronously. +# The handler will execute "/bin/ls" on the current directory and +# read the result. +# + +import kore +import json + +async def async_proc(req): + # + # You may specify a timeout when creating the kore.proc object. + # If the timeout is reached before the process exits kore will + # raise a TimeoutError exception. + # + # Ex: set timeout to 100ms: + # proc = kore.proc("/bin/ls -lR", 100) + + proc = kore.proc("/bin/ls -lR") + + try: + stdout = "" + + # Read until EOF (None is returned) + while True: + chunk = await proc.recv(1024) + if chunk is None: + break + stdout += chunk.decode() + + # Reap the process. + retcode = await proc.reap() + + # Respond with the return code + the result as JSON. + payload = { + "retcode": retcode, + "stdout": stdout + } + + data = json.dumps(payload, indent=4) + req.response(200, data.encode()) + except Exception as e: + # If an exception occurs we must kill the process first. + proc.kill() + errmsg = "Exception: %s" % e + req.response(500, errmsg.encode()) diff --git a/examples/python-async/src/async_queue.py b/examples/python-async/src/async_queue.py @@ -0,0 +1,57 @@ +# +# Copyright (c) 2018 Joris Vink <joris@coders.se> +# +# Permission to use, copy, modify, and distribute this software for any +# purpose with or without fee is hereby granted, provided that the above +# copyright notice and this permission notice appear in all copies. +# +# THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES +# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF +# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR +# ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES +# WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN +# ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF +# OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. +# + +# +# Asynchronous queue example. +# + +import kore + +# The shared queue. +tq = kore.queue() + +# Entry point for our independent coroutine that is created when kore starts. +async def queue_helper(): + while True: + # Wait for a dictionary to arrive. + obj = await tq.pop() + kore.log(kore.LOG_INFO, "coro(): received %s" % obj) + + # Create a message to send back. + msg = "%d = %s" % (kore.time(), obj["msg"]) + + # Send it on the received queue. + obj["rq"].push(msg) + +async def async_queue(req): + # Create our own queue. + rq = kore.queue() + + # The dictionary we are going to send. + obj = { + # Receive queue object. + "rq": rq, + "msg": "hello" + } + + # Push it onto the tq queue now, which will wake up the other coroutine. + tq.push(obj) + + # Wait for a response. + response = await rq.pop() + + # Send the response to the client. + req.response(200, response.encode()) diff --git a/examples/python-async/src/setup.py b/examples/python-async/src/setup.py @@ -0,0 +1,23 @@ +# +# Copyright (c) 2018 Joris Vink <joris@coders.se> +# +# Permission to use, copy, modify, and distribute this software for any +# purpose with or without fee is hereby granted, provided that the above +# copyright notice and this permission notice appear in all copies. +# +# THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES +# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF +# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR +# ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES +# WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN +# ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF +# OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. +# + +import kore + +from async_queue import queue_helper + +# Kore worker started, start the queue helper coroutine. +def kore_worker_configure(): + kore.task_create(queue_helper())