Skip to content

Commit

Permalink
Maintenance: Add support for memcached (via the 'dalli' gem) as Rails…
Browse files Browse the repository at this point in the history
… cache store.

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

See also zammad#1601
  • Loading branch information
mgruner committed Jul 2, 2021
1 parent 2c59c60 commit f05f8e2
Show file tree
Hide file tree
Showing 14 changed files with 90 additions and 20 deletions.
21 changes: 17 additions & 4 deletions .gitlab/ci/base.yml
Original file line number Diff line number Diff line change
Expand Up @@ -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:
Expand Down Expand Up @@ -133,17 +144,19 @@
- <<: *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
- <<: *docker_elasticsearch
- <<: *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'
Expand Down
6 changes: 3 additions & 3 deletions .gitlab/ci/browser-core.yml
Original file line number Diff line number Diff line change
Expand Up @@ -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:
Expand Down Expand Up @@ -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"

Expand All @@ -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"
Expand Down
2 changes: 1 addition & 1 deletion .gitlab/ci/browser-integration.yml
Original file line number Diff line number Diff line change
Expand Up @@ -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:
Expand Down
2 changes: 1 addition & 1 deletion .gitlab/ci/rspec.yml
Original file line number Diff line number Diff line change
Expand Up @@ -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"
Expand Down
4 changes: 2 additions & 2 deletions .gitlab/ci/rspec/mysql.yml
Original file line number Diff line number Diff line change
@@ -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
4 changes: 2 additions & 2 deletions .gitlab/ci/rspec/postgresql.yml
Original file line number Diff line number Diff line change
@@ -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
2 changes: 1 addition & 1 deletion .gitlab/ci/unit/mysql.yml
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
unit:mysql:
stage: test
extends:
- .services_mysql_redis
- .services_mysql_redis_memcached
- .template_unit
2 changes: 1 addition & 1 deletion .gitlab/ci/unit/postgresql.yml
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
unit:postgresql:
stage: test
extends:
- .services_postgresql_redis
- .services_postgresql_redis_memcached
- .template_unit
20 changes: 17 additions & 3 deletions .gitlab/configure_environment.rb
Original file line number Diff line number Diff line change
Expand Up @@ -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')
Expand Down Expand Up @@ -103,6 +116,7 @@ def self.write_env_file

def self.run
configure_redis
configure_memcached
configure_database
write_env_file
end
Expand Down
12 changes: 10 additions & 2 deletions config/application.rb
Original file line number Diff line number Diff line change
Expand Up @@ -47,10 +47,18 @@ class Application < Rails::Application
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
Expand Down
7 changes: 7 additions & 0 deletions config/initializers/log_cache_store.rb
Original file line number Diff line number Diff line change
@@ -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
7 changes: 7 additions & 0 deletions config/initializers/log_websocket_session_store.rb
Original file line number Diff line number Diff line change
@@ -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
5 changes: 5 additions & 0 deletions test/unit/notification_factory_mailer_test.rb
Original file line number Diff line number Diff line change
Expand Up @@ -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])
Expand Down
16 changes: 16 additions & 0 deletions test/unit/ticket_notification_test.rb
Original file line number Diff line number Diff line change
Expand Up @@ -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'
Expand Down Expand Up @@ -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'
Expand Down Expand Up @@ -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'
Expand Down Expand Up @@ -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'
Expand Down

0 comments on commit f05f8e2

Please sign in to comment.