SharedArea – share memory pages between uWSGI components
Warning
SharedArea is a very low-level mechanism.For an easier-to-use alternative, see the Caching and Queue frameworks.
Warning
This page refers to “new generation” sharedarea introduced in uWSGI 1.9.21, the older API is no longer supported.
The sharedarea subsystem allows you to share pages of memory between your uWSGI components (workers, spoolers, mules, etc.)in a very fast (and safe) way.
Contrary to the higher-level caching framework, sharedarea operations are way faster (a single copy instead of the double, as required by caching) and offersvarious optimizations for specific needs.
Each sharedarea (yes, you can have multiple areas) has a size (generally specified in the number of pages), so if you need an 8 KiB shared area on a system with 4 KiB pages, you would use sharedarea=2
.
The sharedarea subsystem is fully thread-safe.
Simple option VS keyval
The sharedarea subsystem exposes (for now) a single option: —sharedarea
.
It takes two kinds of arguments: the number of pages (simple approach) or a keyval arg (for advanced tuning).
The following keyval keys are available:
pages
– set the number of pagesfile
– create the sharedarea from a file that will bemmap
edfd
– create the sharedarea from a file descriptor that will bemmap
edsize
– mainly useful with thefd
andptr
keys to specify the size of the map (can be used as a shortcut to avoid calculation of thepages
value too)ptr
– directly map the area to the specified memory pointer.
The API
The API is pretty big, the sharedarea will be the de-facto toy for writing highly optimized web apps (especially for embedded systems).
Most of the documented uses make sense on systems with slow CPUs or very small amounts of memory.
sharedarea_read(id, pos[, len])
- Read
len
bytes from the specified sharedarea starting at offsetpos
. Iflen
is not specified, the memory will be read til the end (starting frompos
). sharedarea_write(id, pos, string)
- Write the specified
string
(it is language-dependent, obviously) to the specified sharedarea at offsetpos
. sharedarea_read8|16|32|64(id, pos)
- Read a signed integer (8, 16, 32 or 64 bit) from the specified position.
sharedarea_write8|16|32|64(id, pos)
- Write a signed integer (8, 16, 32 or 64 bit) to the specified position.
sharedarea_inc8|16|32|64(id, pos)
- Increment the signed integer (8, 16, 32 or 64 bit) at the specified position.
sharedarea_dec8|16|32|64(id, pos)
- Decrement the signed integer (8, 16, 32 or 64 bit) at the specified position.
sharedarea_wait(id[, freq, timeout])
- Wait for modifications of the specified sharedarea (see below).
sharedarea_rlock(id)
- lock a shared area for read (use only if you know what you are doing, generally the sharedarea api functions implement locking by themselves)
sharedarea_wlock(id)
- lock a shared area for write (use only if you know what you are doing, generally the sharedarea api functions implement locking by themselves)
sharedarea_unlock(id)
- unlock a shared area (use only if you know what you are doing, generally the sharedarea api functions implement locking by themselves)
Waiting for updates
One of the most powerful features of sharedareas (compared to caching) is “waiting for updates”. Your worker/thread/async_core can be suspendeduntil a sharedarea is modified.
Technically, a millisecond-resolution timer is triggered, constantly checking for updates (the operation is very fast, as the sharedarea object has an update counter, so we only need to check that value for changes).
Optional API
The following functions require specific features from the language, so not all of the language plugins are able to support them.
sharedarea_readfast(id, pos, object, [, len])
- Read
len
bytes from the specified sharedarea starting at offsetpos
to the specified object. Iflen
is not specified, the memory will be read til the end (starting frompos
).Currently is implemented only for Perl. sharedarea_memoryview(id)
- returns python memoryview object you can directly manipulate (works only on CPython)
sharedarea_object(id)
- some plugin exposes an alternative way to create sharedareas from internal objects. This functions returns the original object (currently implemented only on CPython on top of bytearrays using
—py-sharedarea <size>
option)
Websockets integration API
This is currently supported only in the psgi/perl plugin:
websocket_send_from_sharedarea(id, pos)
- send a websocket message directly from the specified sharedarea
websocket_send_binary_from_sharedarea(id, pos)
- send a websocket binary message directly from the specified sharedarea
Advanced usage (from C)
Work in progress.
Check https://github.com/unbit/uwsgi-capture for an example of sharedarea managed from C