State Storage
RBCli supports both local and remote state storage. This is done by synchronizing a Hash with either the local disk or a remote database.
Local State
RBCli's local state storage gives you access to a hash that is automatically persisted to disk when changes are made.
Configuration
You can configure it in config/storage.rb
.
local_state '/var/mytool/localstate', force_creation: true, halt_on_error: true
There are three parameters to configure it with:
- The
path
as a string (self-explanatory) force_creation
- This will attempt to create the path and file if it does not exist (equivalent to an
mkdir -p
andtouch
in linux)
- This will attempt to create the path and file if it does not exist (equivalent to an
halt_on_error
- RBCli's default behavior is to raise an exception if the file can not be created, read, or updated at any point in time
- If this is set to
false
, RBCli will silence any errors pertaining to file access and will fall back to whatever data is available. Note that if this is enabled, changes made to the state may not be persisted to disk.- If creation fails and file does not exist, you start with an empty hash
- If file exists but can't be read, you will have an empty hash
- If file can be read but not written, the hash will be populated with the data. Writes will be stored in memory while the application is running, but will not be persisted to disk.
Access and Usage
Once configured you can access it with a standard hash syntax in your Standard Commands:
Rbcli.local_state[:yourkeyhere]
The methods available for use at the top level are as follows:
Hash native methods:
[]
(Regular hash syntax. Keys are accessed via either symbols or strings indifferently.)[]=
(Assignment operator)delete
each
key?
Additional methods:
commit
- Every assignment to the top level of the hash will result in a write to disk (for example:
Rbcli.local_state[:yourkey] = 'foo'
). However, if you are manipulating nested hashes, these saves will not be triggered. You can trigger them manually by callingcommit
.
- Every assignment to the top level of the hash will result in a write to disk (for example:
clear
- Resets the data back to an empty hash.
refresh
- Loads the most current version of the data from the disk
disconnect
- Removes the data from memory and sets
Rbcli.local_state = nil
. Data will be read from disk again on next access.
- Removes the data from memory and sets
Every assignment will result in a write to disk, so if an operation will require a large number of assignments/writes it should be performed to a different hash before beign assigned to this one.
Remote State
RBCli's remote state storage gives you access to a hash that is automatically persisted to a remote storage location when changes are made. It has optional locking built-in, meaning that multiple users may share remote state without any data consistency issues.
Currently, this feature requires AWS DynamoDB, though other backend systems will be added in the future.
Configuration
Before DynamoDB can be used, AWS API credentials have to be created and made available. RBCli will attempt to find credentials from the following locations in order:
- User's config file
- Environment variables
AWS_ACCESS_KEY_ID
andAWS_SECRET_ACCESS_KEY
- User's AWSCLI configuration at
~/.aws/credentials
For more information about generating and storing AWS credentials, see Configuring the AWS SDK for Ruby. Please make sure that your users are aware that they will need to provide their own credentials to use this feature.
You can configure it in config/storage.rb
.
remote_state_dynamodb table_name: 'mytable', region: 'us-east-1', force_creation: true, halt_on_error: true, locking: false
These are the parameters:
table_name
- The name of the DynamoDB table to use.
region
- The AWS region that the database is located
force_creation
- Creates the DynamoDB table if it does not already exist
halt_on_error
- Similar to the way Local State works, setting this to
false
will silence any errors in connecting to the DynamoDB table. Instead, your application will simply have access to an empty hash that does not get persisted anywhere. - This is good for use cases that involve using this storage as a cache, where a connection error might mean the feature doesn't work but its not important enough to interrupt the user.
- Similar to the way Local State works, setting this to
locking
- Setting this to
true
enables locking, meaning only one instance of your application can access the shared data at any given time. For more information see Distributed State Locking.
- Setting this to
Access and Usage
Once configured you can access it with a standard hash syntax:
Rbcli.remote_state[:yourkeyhere]
This works the same way that Local State does, with the same performance caveats (try not to write too frequently).
Note that all state in Rbcli is lazy-loaded, so no connections will be made until your code attempts to access the data even if the feature is enabled.
For more information on the available commands, see the documentation on Local State