Maintenance: Add support for memcached (via the 'dalli' gem) as Rails cache store.

To activate this, simply specify MEMCACHE_SERVERS=your.server and Zammad will use that as Rails cache store.

See also https://github.com/zammad/zammad/issues/1601
This commit is contained in:
Martin Gruner 2021-07-02 11:46:37 +00:00
parent 2c59c60adb
commit f05f8e2d3c
14 changed files with 90 additions and 20 deletions

View file

@ -68,41 +68,52 @@
name: redis:latest
alias: redis
.docker_memcached: &docker_memcached
name: memcached:latest
alias: memcached
command: ["memcached", "-m", "256M"]
# service templates
.services_mysql: &services_mysql
services:
- <<: *docker_mysql
.services_mysql_redis: &services_mysql_redis
.services_mysql_redis_memcached: &services_mysql_redis_memcached
variables:
REDIS_URL: "redis://redis:6379"
MEMCACHE_SERVERS: "memcached"
services:
- <<: *docker_mysql
- <<: *docker_redis
- <<: *docker_memcached
.services_postgresql: &services_postgresql
services:
- <<: *docker_postgresql
.services_postgresql_redis: &services_postgresql_redis
.services_postgresql_redis_memcached: &services_postgresql_redis_memcached
variables:
REDIS_URL: "redis://redis:6379"
MEMCACHE_SERVERS: "memcached"
services:
- <<: *docker_postgresql
- <<: *docker_redis
- <<: *docker_memcached
.services_mysql_postgresql: &services_mysql_postgresql
services:
- <<: *docker_mysql
- <<: *docker_postgresql
.services_mysql_postgresql_redis: &services_mysql_postgresql_redis
.services_mysql_postgresql_redis_memcached: &services_mysql_postgresql_redis_memcached
variables:
REDIS_URL: "redis://redis:6379"
MEMCACHE_SERVERS: "memcached"
services:
- <<: *docker_mysql
- <<: *docker_postgresql
- <<: *docker_redis
- <<: *docker_memcached
.services_postgresql_selenium: &services_postgresql_selenium
services:
@ -133,10 +144,11 @@
- <<: *docker_selenium
- <<: *docker_imap
.services_mysql_postgresql_elasticsearch_selenium_imap_redis: &services_mysql_postgresql_elasticsearch_selenium_imap_redis
.services_mysql_postgresql_elasticsearch_selenium_imap_redis_memcached: &services_mysql_postgresql_elasticsearch_selenium_imap_redis_memcached
variables:
ELASTICSEARCH_TAG: 'stable'
REDIS_URL: "redis://redis:6379"
MEMCACHE_SERVERS: "memcached"
services:
- <<: *docker_mysql
- <<: *docker_postgresql
@ -144,6 +156,7 @@
- <<: *docker_selenium
- <<: *docker_imap
- <<: *docker_redis
- <<: *docker_memcached
# we need at least one job to store and include this template
# but we skip this via 'only' -> 'variables' -> '$IGNORE'

View file

@ -19,7 +19,7 @@ include:
- .env_base
- .variables_es
- .variables_app_restart_cmd
- .services_mysql_postgresql_elasticsearch_selenium_imap_redis
- .services_mysql_postgresql_elasticsearch_selenium_imap_redis_memcached
variables:
RAILS_ENV: "production"
script:
@ -53,7 +53,7 @@ include:
extends:
- .env_base
- .variables_app_restart_cmd
- .services_mysql_postgresql_redis
- .services_mysql_postgresql_redis_memcached
variables:
RAILS_ENV: "production"
@ -63,7 +63,7 @@ include:
extends:
- .env_base
- .variables_es
- .services_mysql_postgresql_elasticsearch_selenium_imap_redis
- .services_mysql_postgresql_elasticsearch_selenium_imap_redis_memcached
variables:
RAILS_ENV: "test"
REDIS_URL: "redis://redis:6379"

View file

@ -15,7 +15,7 @@ include:
- .env_base
- .variables_app_restart_cmd
- .variables_es
- .services_mysql_postgresql_elasticsearch_selenium_imap_redis
- .services_mysql_postgresql_elasticsearch_selenium_imap_redis_memcached
variables:
RAILS_ENV: "test"
script:

View file

@ -36,7 +36,7 @@ rspec:integration:
stage: test
extends:
- .env_base
- .services_mysql_postgresql_redis
- .services_mysql_postgresql_redis_memcached
- .rspec_integration_rules
variables:
RAILS_ENV: "test"

View file

@ -1,11 +1,11 @@
rspec:mysql:
stage: test
extends:
- .services_mysql_redis
- .services_mysql_redis_memcached
- .template_rspec
rspec:mysql:db_reset:
stage: test
extends:
- .services_mysql_redis
- .services_mysql_redis_memcached
- .template_rspec_db_reset

View file

@ -1,11 +1,11 @@
rspec:postgresql:
stage: test
extends:
- .services_postgresql_redis
- .services_postgresql_redis_memcached
- .template_rspec
rspec:postgresql:db_reset:
stage: test
extends:
- .services_postgresql_redis
- .services_postgresql_redis_memcached
- .template_rspec_db_reset

View file

@ -1,5 +1,5 @@
unit:mysql:
stage: test
extends:
- .services_mysql_redis
- .services_mysql_redis_memcached
- .template_unit

View file

@ -1,5 +1,5 @@
unit:postgresql:
stage: test
extends:
- .services_postgresql_redis
- .services_postgresql_redis_memcached
- .template_unit

View file

@ -23,17 +23,30 @@ class ConfigureEnvironment
def self.configure_redis
if ENV['REDIS_URL'].nil? || ENV['REDIS_URL'].empty? # rubocop:disable Rails/Blank
puts 'Redis is not available, using File as web socket session back end.'
puts 'Redis is not available, using File as web socket session store.'
return
end
if [true, false].sample
puts 'Using Redis as web socket session back end.'
puts 'Using Redis as web socket session store.'
return
end
puts 'Using File as web socket session back end.'
puts 'Using File as web socket session store.'
@env_file_content += "unset REDIS_URL\n"
end
def self.configure_memcached
if ENV['MEMCACHE_SERVERS'].nil? || ENV['MEMCACHE_SERVERS'].empty? # rubocop:disable Rails/Blank
puts 'Memcached is not available, using File as Rails cache store.'
return
end
if [true, false].sample
puts 'Using memcached as Rails cache store.'
return
end
puts "Using Zammad's file store as Rails cache store."
@env_file_content += "unset MEMCACHE_SERVERS\n"
end
def self.configure_database # rubocop:disable Metrics/AbcSize, Metrics/CyclomaticComplexity, Metrics/PerceivedComplexity
if File.exist? File.join(__dir__, '../config/database.yml')
@ -103,6 +116,7 @@ class ConfigureEnvironment
def self.run
configure_redis
configure_memcached
configure_database
write_env_file
end

View file

@ -47,10 +47,18 @@ module Zammad
config.api_path = '/api/v1'
# define cache store
config.cache_store = :zammad_file_store, Rails.root.join('tmp', "cache_file_store_#{Rails.env}"), { expires_in: 7.days }
config.cache_store = if ENV['MEMCACHE_SERVERS'].present?
[:mem_cache_store, ENV['MEMCACHE_SERVERS'], { expires_in: 7.days }]
else
[:zammad_file_store, Rails.root.join('tmp', "cache_file_store_#{Rails.env}"), { expires_in: 7.days }]
end
# define websocket session store
config.websocket_session_store = ENV['REDIS_URL'] ? :redis : :file
config.websocket_session_store = if ENV['REDIS_URL'].present?
:redis
else
:file
end
# Rails 6.1 returns false when the enqueuing is aborted.
config.active_job.return_false_on_aborted_enqueue = true

View file

@ -0,0 +1,7 @@
# Copyright (C) 2012-2021 Zammad Foundation, http://zammad-foundation.org/
if Rails.application.config.cache_store.first.eql? :mem_cache_store
Rails.logger.info 'Using memcached as Rails cache store.'
else
Rails.logger.info "Using Zammad's file store as Rails cache store."
end

View file

@ -0,0 +1,7 @@
# Copyright (C) 2012-2021 Zammad Foundation, http://zammad-foundation.org/
if Rails.application.config.websocket_session_store.eql? :redis
Rails.logger.info 'Using Redis as web socket session store.'
else
Rails.logger.info 'Using File as web socket session store.'
end

View file

@ -281,6 +281,11 @@ class NotificationFactoryMailerTest < ActiveSupport::TestCase
agent1.save
travel 30.seconds
if Rails.application.config.cache_store.first.eql? :mem_cache_store
# External memcached does not support time travel, so clear the cache to avoid an outdated match.
Cache.clear
end
result = NotificationFactory::Mailer.notification_settings(agent1, ticket1, 'create')
assert_equal(true, result[:channels][:online])
assert_equal(true, result[:channels][:email])

View file

@ -666,6 +666,10 @@ class TicketNotificationTest < ActiveSupport::TestCase
@agent2.save!
travel 1.minute # to skip loopup cache in Transaction::Notification
if Rails.application.config.cache_store.first.eql? :mem_cache_store
# External memcached does not support time travel, so clear the cache to avoid an outdated match.
Cache.clear
end
# create ticket in group
ApplicationHandleInfo.current = 'scheduler.postmaster'
@ -732,6 +736,10 @@ class TicketNotificationTest < ActiveSupport::TestCase
@agent2.save!
travel 1.minute # to skip loopup cache in Transaction::Notification
if Rails.application.config.cache_store.first.eql? :mem_cache_store
# External memcached does not support time travel, so clear the cache to avoid an outdated match.
Cache.clear
end
# create ticket in group
ApplicationHandleInfo.current = 'scheduler.postmaster'
@ -798,6 +806,10 @@ class TicketNotificationTest < ActiveSupport::TestCase
@agent2.save!
travel 1.minute # to skip loopup cache in Transaction::Notification
if Rails.application.config.cache_store.first.eql? :mem_cache_store
# External memcached does not support time travel, so clear the cache to avoid an outdated match.
Cache.clear
end
# create ticket in group
ApplicationHandleInfo.current = 'scheduler.postmaster'
@ -877,6 +889,10 @@ class TicketNotificationTest < ActiveSupport::TestCase
@agent2.save!
travel 1.minute # to skip loopup cache in Transaction::Notification
if Rails.application.config.cache_store.first.eql? :mem_cache_store
# External memcached does not support time travel, so clear the cache to avoid an outdated match.
Cache.clear
end
# create ticket in group
ApplicationHandleInfo.current = 'scheduler.postmaster'