Currently, the ResultCache is instantiated within the DataSource class:
def result_cache
@result_cache ||= Blazer::ResultCache.new(self)
end
This makes it difficult to develop extensions for Blazer such as acting on query results.
Proposed Changes
Allow ResultCache to be injected when initializing DataSource.
Implement a mechanism (similar to ActiveSupport callbacks) to extend ResultCache functionality.
Add a configuration option to specify a custom ResultCache class in the Blazer settings.
Use Case
My end goal is to create an extension for Blazer that records both query and result history. ResultCache seems like the most straightforward way to capture queries and results in transit.
Current Workaround
Currently using a non-invasive approach by setting Blazer.cache to a thin wrapper around Rails.cache. This wrapper sends ActiveSupport notifications (e.g., blazer.cache_write) that can be subscribed to. However, this method loses context, such as the original query, as it only provides access to the cache key and result.
Benefits
Improved flexibility and extensibility of the caching mechanism.
Ability to capture more context (e.g., original query) when caching results.
Easier implementation of query and result history tracking.
Proposed Implementation
Modify the DataSource class to accept a custom ResultCache instance, (showing both a DI example and a settings -> constantization example:
module Blazer
class DataSource
# ...
def initialize(id, settings, result_cache = nil)
@id = id
@settings = settings
@result_cache = result_cache
end
# ...
def result_cache
@result_cache ||= begin
cache_class = settings["result_cache_class"]
cache_class ? cache_class.constantize.new(self) : Blazer::ResultCache.new(self)
end
end
# ...
end
end
Implement an extension mechanism for ResultCache, possibly using ActiveSupport::Callbacks:
module Blazer
class ResultCache
include ActiveSupport::Callbacks
define_callbacks :cache_write, :cache_read, :cache_delete
def initialize(data_source)
@data_source = data_source
end
def read_statement(statement)
run_callbacks :cache_read do
# Existing read logic
end
end
def write_statement(statement, result, options = {})
run_callbacks :cache_write do
# Existing write logic
end
end
def delete_statement(statement)
run_callbacks :cache_delete do
# Existing delete logic
end
end
# Implement similar changes for read_run, write_run, and delete_run methods
end
end
Implement a way for the user to specify a custom ResultCache
Setting a Custom ResultCache
This is the more complicated part from a dev experience perspective. If doing the settings based approach I outlined above, an implementation could be something like this, but curious to know what you think:
Feature Request
Current Behavior
Currently, the
ResultCache
is instantiated within theDataSource
class:This makes it difficult to develop extensions for Blazer such as acting on query results.
Proposed Changes
ResultCache
to be injected when initializingDataSource
.ResultCache
functionality.ResultCache
class in the Blazer settings.Use Case
My end goal is to create an extension for Blazer that records both query and result history.
ResultCache
seems like the most straightforward way to capture queries and results in transit.Current Workaround
Currently using a non-invasive approach by setting
Blazer.cache
to a thin wrapper aroundRails.cache
. This wrapper sends ActiveSupport notifications (e.g.,blazer.cache_write
) that can be subscribed to. However, this method loses context, such as the original query, as it only provides access to the cache key and result.Benefits
Proposed Implementation
DataSource
class to accept a customResultCache
instance, (showing both a DI example and a settings -> constantization example:ResultCache
, possibly using ActiveSupport::Callbacks:ResultCache
Setting a Custom ResultCache
This is the more complicated part from a dev experience perspective. If doing the settings based approach I outlined above, an implementation could be something like this, but curious to know what you think:
Thank you for all that you do! 🙏