Since the User DB is not going to be large cache the users
in local memory and sync with the DB when changes are
made to the local user store.
Signed-off-by: Eric Callahan <arksine.code@gmail.com>
Now that all transactions run in a thread it is possible for them to
interleave. The record based operations allow for batch operations
within a single transaction.
Signed-off-by: Eric Callahan <arksine.code@gmail.com>
Wrap command implementations in with a _run_command() method. All
database commands now return a Future object. If the command was
run before the eventloop starts its possible to immediately query
the Future's result.
Signed-off-by: Eric Callahan <arksine.code@gmail.com>
Similar to the update method, however sync will remove any
keys in the database not in the new value.
Signed-off-by: Eric Callahan <arksine.code@gmail.com>
Rather than creating two wrappers, use a single wrapper whose methods
always return a future or awaitable. If the operation occurs during
the __init__() method of a component it will be syncrhonous, and the
result from the future can be immediately queried.
Signed-off-by: Eric Callahan <arksine.code@gmail.com>
Rather than reading out the entire database, attempt to pop off
empty keys in each database. This should should speed up
init on platforms with slow disk I/O and prevents reading
large namespaces in memory.
Signed-off-by: Eric Callahan <arksine.code@gmail.com>
It isn't necessary to read out the entire namespace, just attempt
to fetch the record and reduce the key list.
Signed-off-by: Eric Callahan <arksine.code@gmail.com>
Since transactions are now threaded we need updating
and clearing a namespace needs to be performed within
one transaction.
Signed-off-by: Eric Callahan <arksine.code@gmail.com>
Database transactions can perform disk I/O tasks, which at times will
block the eventloop. Run all transactions in threads to prevent this
from occuring.
Signed-off-by: Eric Callahan <arksine.code@gmail.com>
This adds the framework for unit testing Moonraker via pytest.
Initally only moonraker.py, klippy_connection.py, and confighelper.py
have acceptable coverage. Coverage for other modules will be added on
an incremental basis, when most of Moonraker's source is covered tests
will be conducted via GitHub actions.
Signed-off-by: Eric Callahan <arksine.code@gmail.com>
The read() method will return an empty list if the file specified
does not exist or if the read failed in some fashion.
Signed-off-by: Eric Callahan <arksine.code@gmail.com>
Moonraker requires that some Klipper objects be configured
and loaded. This check has always been performed and logged,
now track and report missing requirements.
Signed-off-by: Eric Callahan <arksine.code@gmail.com>
Move the KlippyConnection class into its own module. Refactor
init to use loops rather than callbacks, this reduces complexity
of tracking and cancelling callback handles.
All Klippy state previously tracked by the Server is now in the
KlippyConnection. This improves testing and makes the code
less ambiguous, ie: the `server.make_request()` method is not
as clear as `klippy.request()`.
Signed-off-by: Eric Callahan <arksine.code@gmail.com>
Move the version check to the top of the module. An older version
of python is unlikely to make it beyond the initial import statements,
so print a message to stdout and stderr.
Move argument parsing out of the main method. This makes it possible
to invoke main without parsing command line arguments, which is useful
for tests.
Signed-off-by: Eric Callahan <arksine.code@gmail.com>
Rather than instantiate a new version of the event loop wrapper
we can simply reset the internal event loop.
Signed-off-by: Eric Callahan <arksine.code@gmail.com>
Don't load components and start the server from within the
__init__() method. Break those out and call them in __main__().
This makes unit testing individual components possible.
Signed-off-by: Eric Callahan <arksine.code@gmail.com>
Dont directly import components for instance checks. Instead
check to see if the type is serializable, if not store the string
representation.
Signed-off-by: Eric Callahan <arksine.code@gmail.com>
The result should be a dictionary of dictionaries rather than a
dictionary of SectionProxy objects.
Signed-off-by: Eric Callahan <arksine.code@gmail.com>
Attempt to take a backup of the configuration file if Moonraker
loads successfully and has not seen a config change.
If Moonraker fails to load due to a config error, attempt to fallback
to the backup configuration. If that fails, exit the server.
Signed-off-by: Eric Callahan <arksine.code@gmail.com>
Its safer to let the attempt to read fail before additional error
checking. Also there is no need to remove DEFAULT from
config.sections(), as it can't be there per the Python docs.
Signed-off-by: Eric Callahan <arksine.code@gmail.com>
Don't exit the server if the log path is invalid. Instead start
logging to stdout and add a warning for the user to
resolve.
Signed-off-by: Eric Callahan <arksine.code@gmail.com>