Skip to content

Fix Read-Only Errors for Cache Deletion in MultiDB Setup with database_selector #238

@Dandush03

Description

@Dandush03

Description

When using Rails' MultiDB configuration with database_selector, attempts to delete entries from the SolidCache::Entry model may result in a read-only error. This issue arises because the database_selector configuration causes certain operations to route to the replica database, which is read-only.

The Error

The following error occurs when the application tries to execute a DELETE query in a replica marked as read-only by rails middleware

ActionView::Template::Error (Write query attempted while in readonly mode: DELETE FROM "solid_cache_entries" WHERE "solid_cache_entries"."key_hash" = 8850981528477303422)

This error disrupts operations that rely on cache clearing, such as session management or dynamic cache updates.

Reproduction Steps

  1. Add the following configuration to your Rails app:
Rails.application.configure do
  config.active_record.database_selector = { delay: 2.seconds }
  config.active_record.database_resolver = ActiveRecord::Middleware::DatabaseSelector::Resolver
  config.active_record.database_resolver_context = ActiveRecord::Middleware::DatabaseSelector::Resolver::Session
end
  1. Configure a primary and replica database in database.yml.

  2. Attempt to delete a cache entry using SolidCache::Entry in a context where the replica database connection is active.
    Observe the error described above.

Hint: I suggest using devise user_sign_in? method in an index action since it would make it easier to reproduce

Expected Behavior

Cache-related models like SolidCache::Entry should always use the writable primary database for operations that require modifications, regardless of the database_selector configuration.

My current solution:

# config/initializer/override_read_only_for_cache.rb
module OverrideReadOnlyForCache
  def readonly?
    false
  end
end

Rails.application.config.after_initialize do
  SolidCache::Entry.prepend(OverrideReadOnlyForCache)
end

This ensures that the model is always writable, bypassing the default read-only behavior in a MultiDB setup.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions