GitHub – oldmoe/litestack
December 23, 2024

GitHub – oldmoe/litestack


All your data infrastructure is in gem!

Litestack is a Ruby gem that provides an all-in-one solution for web application data infrastructure for Ruby and Ruby on Rails applications. It leverages the power and embeddability of SQLite to provide a mature SQL database, fast cache, powerful job queue, reliable message agent, full-text search engine and metrics platform in one package.

Litestack delivers superior performance, efficiency, ease of use and cost savings compared to traditional approaches that require separate servers and databases. Its embedded database and cache reduce memory and CPU usage, while its simple interface simplifies the development process. Overall, Litestack sets a new standard for web application development and is an excellent choice for anyone who needs speed, efficiency, and simplicity.

You can read more about why litestack can be a good choice for your next web application here,You may also be interested in litestack benchmark.

With litestack, you only need to add a new gem to your application, which will replace many other gems and services. For example, a typical Rails application using litestack will no longer require the following services:

  • Database server (e.g. PostgreSQL, MySQL)
  • Cache server (such as Redis, Memcached)
  • Job processor (e.g. Sidekiq, Goodjob)
  • Pubsub server (e.g. Redis, PostgreSQL)
  • Full-text search server (e.g. Elasticsearch, Meilisearch)

To make it more efficient, litestack will detect the presence of Fiber-based IO frameworks such as Async (for example, when you use Falcon web server) or Polyphony. It then switches its caching and queuing background workers to fibers (using the semantics of the existing framework). This is done transparently and often results in lower CPU and memory utilization.

Add to litestack The gem line is added to the application’s Gemfile:

To configure a Rails application to run a complete litestack, run:

$ rails generate litestack:install

litestack currently offers six main components

  • Wright Database
  • Lite cache
  • Streamline work
  • wired
  • Refine search
  • literal

litedb is a wrapper for SQLite3 that provides better default configurations, tuned for concurrency and performance. Out of the box, litedb works seamlessly across multiple processes without database lock errors. litedb can be used in a variety of ways, including:

litedb can be used exactly like the SQLite3 gem because litedb inherits from SQLite3

require 'litestack'
db = Litedb.new(path_to_db)
db.execute("create table users(id integer primary key, name text)")
db.execute("insert into users(name) values (?)", "Hamada")
db.query("select count(*) from users") # => [[1]]

litedb provides tight Rails/ActiveRecord integration, which can be configured as follows

In database.yml

adapter: litedb
# normal sqlite3 configuration follows

litedb provides integration with the Sequel database toolkit, which can be configured as follows

DB = Sequel.connect("litedb://path_to_db_file")

litecache is a high-speed, low-overhead caching library that uses SQLite as the backend. litecache can be seamlessly accessed from multiple programs on the same machine. It also features key expiration, LRU-based eviction, and integer value increment/decrement.

require 'litestack'
cache = Litecache.new(path: "path_to_file")
cache.set("key", "value")
cache.get("key") #=> "value"

In your desired environment file (e.g. production.rb)

config.cache_store = :litecache, {path: './path/to/your/cache/file'}

This provides transparent integration using the Rails caching interface

litecache will spawn a background thread for cleanup. If it is detected that the current environment has fiber::scheduler or polyphony Once loaded, it spawns a fiber, saving memory and CPU cycles.

For more information about Litejob, see Streamlining work guide

litejob is a fast and very efficient job queue processor for Ruby applications. It is also built on SQLite, providing transaction guarantees, durability and excellent performance.

require 'litestack'
# define your job class
class MyJob
  include ::Litejob
      
  queue = :default
      
  # must implement perform, with any number of params
  def perform(params)
    # do stuff
  end
end
    
#schedule a job asynchronusly
MyJob.perform_async(params)
    
#schedule a job at a certain time
MyJob.perform_at(time, params)
    
#schedule a job after a certain delay
MyJob.perform_after(delay, params)

In your desired environment file (e.g. production.rb)

config.active_job.queue_adapter = :litejob

You can add more configuration in litejob.yml (or in config/litejob.yml if you want to integrate with Rails)

queues:
    - [default, 1]
    - [urgent, 5]
    - [critical, 10, "spawn"]

The queue needs to contain a name and priority (a number between 1 and 10), and optionally a new flag “spawn”, which means each job will execute in its own concurrency context (thread or fiber)

This is a replacement adapter for replacing the operating cable async and other production adapters (e.g. PostgreSQL, Redis). This adapter is currently only tested in local (inline) mode.

To start and execute Litecable, you need to set the Cable.yaml file in the config/ directory.

cable.yaml

development:
  adapter: litecable

test:
  adapter: test

staging:
  adapter: litecable

production:
  adapter: litecable

Litesearch adds a new full-text search feature to Litedb, you can use it in standalone mode as follows:

require 'litestack/litedb'
db = Litedb.new(":memory:")
# create the index
idx = db.search_index('index_name') do |schema|
    schema.fields [:sender, :receiver, :body]
    schema.field :subject, weight: 10
    schema.tokenizer :trigram
end
# add documents
idx.add({sender: 'Kamal', receiver: 'Laila', subject: 'Are the girls awake?', body: 'I got them the new phones they asked for, are they awake?'})
# search the index, all fields
idx.search('kamal')
# search the index, specific field, partial workd (trigram)
idx.search('subject: awa') 

Litesearch is tightly integrated with ActiveRecord and Sequel. The following is an integration example

class Author < ActiveRecord::Base
    has_many :books
end

class Book < ActiveRecord::Base
    belongs_to :author

    include Litesearch::Model

    litesearch do |schema|
        schema.fields [:title, :description]
        schema.field :author, target: 'authors.name'
        schema.tokenizer :porter
    end
end
# insert records
Author.create(name: 'Adam A. Writer') 
Book.create(title: 'The biggest stunt', author_id: 1, description: 'a description') 
# search the index, the search method integrates with AR's query interface
Book.search('author: writer').limit(1).all
class Author < Sequel::Model
    one_to_many :books
end

class Book < Sequel::Model
    many_to_one :author

    include Litesearch::Model
    litesearch do |schema|
        schema.fields [:title, :description]
        schema.field :author, target: 'authors.name'
        schema.tokenizer :porter
    end
end
# insert records
Author.create(name: 'Adam A. Writer') 
Book.create(title: 'The biggest stunt', author_id: 1, description: 'a description') 
# search the index, the search method integrates with Sequel's query interface
Book.search('author: writer').limit(1).all

Litestack comes with a module that collects useful metrics for its different components. In each component, you need to add the following to the respective .yml file (or database.yml in the case of Litedb)

    metrics: true # default is false

If you enable metrics, it will start collecting data from each module and store them in a database file called metric.db located in the Litesupport.root folder

Litemetric has an API that can collect any metric that is not a litestack category. These indicators will be located in the database, but currently Liteboard can only display correct data for the Litestack module, and will later include displaying arbitrary indicators for other components.

Liteboard is a simple web server that provides a web interface for collected metrics. It should be globally available for use with the helper type.

It allows you to point to a specific indicator database archive or configuration file and then it will display the data from that indicator database

Indicator view example:

  • Database size, number of tables and indexes
  • Number of read/write queries
  • Read/write query ratio over time
  • Read/write query time over time
  • slowest query
  • Most expensive query (total running time = frequency * cost)

  • Cache size, percentage of size limit
  • Number of entries
  • Read/write over time
  • Read hits/misses over time
  • Most written items
  • Most read items

You are welcome to submit bug reports and pull requests on GitHub: https://github.com/oldmoe/litestack.

This gem is provided as open source under the following terms my license.

2024-12-23 02:32:21

Leave a Reply

Your email address will not be published. Required fields are marked *