cell 0.1.1 → 0.1.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,70 +0,0 @@
1
- require 'cell/context'
2
- require 'cell/model'
3
- require 'cell/schema'
4
-
5
- module Cell
6
- class Configuration
7
- attr_accessor :model
8
- attr_accessor :identifier
9
- attr_accessor :data_directory
10
- attr_accessor :sidekiq
11
-
12
- def initialize(model, &block)
13
- @model = model
14
- @identifier = :id
15
- @data_directory = nil
16
- @sidekiq = false
17
-
18
- yield self
19
- commit!(model)
20
- end
21
-
22
- def commit!(model)
23
- fail "model class not specified" if model.nil? || ! model.is_a?(Class)
24
-
25
- configure_model!(model)
26
- configure_data_directory!(model)
27
- configure_sidekiq!(model)
28
- end
29
-
30
- private
31
-
32
- def configure_model!(model)
33
- ->(identifier) do
34
- model.define_singleton_method(:cell_id_column) do
35
- identifier
36
- end
37
- end.call(self.identifier)
38
-
39
- Cell.const_set(:Tenant, model)
40
- model.prepend(::Cell::Model)
41
- model.prepend(::Cell::Schema)
42
- model.prepend(::Cell::Context)
43
- end
44
-
45
- def configure_data_directory!(model)
46
- if self.data_directory
47
- ->(data_directory) do
48
- model.define_singleton_method(:data_directory_root) do
49
- data_directory
50
- end
51
- end.call(self.data_directory.to_s)
52
- model.prepend(::Cell::DataDirectory)
53
- end
54
- end
55
-
56
- def configure_sidekiq!(model)
57
- if self.sidekiq
58
- require 'cell/sidekiq'
59
- ::Cell::Sidekiq.configure!
60
- end
61
- end
62
- end
63
- private_constant :Configuration
64
-
65
- module_function
66
- def configure(model = nil, &block)
67
- fail ArgumentError, "model or block required" if model.nil? && !block_given?
68
- Configuration.new(model || block.binding.receiver, &block)
69
- end
70
- end
@@ -1,42 +0,0 @@
1
- require 'fileutils'
2
-
3
- module Cell
4
- module DataDirectory
5
- module ClassMethods
6
- def data_directory_root
7
- fail NotImplementedError
8
- end
9
-
10
- def data_directory_for_cell_id(cell_id)
11
- cell_id = cell_id.to_s.gsub(/[^a-z0-9_]/i, '-')
12
- File.join(data_directory_root, cell_id)
13
- end
14
- end
15
-
16
- def data_directory
17
- self.class.data_directory_for_cell_id(cell_id)
18
- end
19
-
20
- private
21
- def create_data_directory!
22
- FileUtils.mkdir_p(data_directory)
23
- end
24
-
25
- def update_data_directory!
26
- src, dst = cell_id_change_set
27
- FileUtils.mv(self.class.data_directory_for_cell_id(src), data_directory)
28
- end
29
-
30
- def destroy_data_directory!
31
- FileUtils.rm_rf(data_directory)
32
- end
33
-
34
- def self.prepended(cls)
35
- cls.extend(ClassMethods)
36
-
37
- cls.after_create_commit :create_data_directory!
38
- cls.after_update_commit :update_data_directory!, if: :cell_id_changed?
39
- cls.after_destroy_commit :destroy_data_directory!
40
- end
41
- end
42
- end
data/lib/cell/model.rb DELETED
@@ -1,37 +0,0 @@
1
- require 'cell/schema'
2
- require 'cell/data_directory'
3
-
4
- module Cell
5
- module Model
6
- class << self
7
- attr_accessor :cls
8
- end
9
-
10
- module ClassMethods
11
- def cell_id_column
12
- fail NotImplementedError
13
- end
14
-
15
- def cell_find(cell_id)
16
- find_by(cell_id_column => cell_id)
17
- end
18
- end
19
-
20
- def cell_id
21
- send(self.class.cell_id_column)
22
- end
23
-
24
- def cell_id_changed?
25
- !! previous_changes[self.class.cell_id_column]
26
- end
27
-
28
- def cell_id_change_set
29
- fail "cell_id was not changed" unless cell_id_changed?
30
- previous_changes[self.class.cell_id_column]
31
- end
32
-
33
- def self.prepended(cls)
34
- cls.extend(ClassMethods)
35
- end
36
- end
37
- end
data/lib/cell/sidekiq.rb DELETED
@@ -1,58 +0,0 @@
1
- # This middleware passes along a tenant_id from client to server if a tenant
2
- # is active when a job is spun off. The server process then activates the
3
- # proper tenant if it's detected, so jobs are processed under the context of the
4
- # same tenant that started the job on the client.
5
-
6
-
7
- require 'sidekiq'
8
-
9
- module Cell
10
- module Sidekiq
11
- KEY = 'Cell.cell_id'
12
-
13
- class ClientMiddleware
14
- def call(worker, msg, queue, redis_pool)
15
- if (current_id = ::Cell.current&.cell_id)
16
- msg[KEY] = current_id
17
- end
18
-
19
- yield
20
- true
21
- end
22
- end
23
-
24
- class ServerMiddleware
25
- def call(worker, msg, queue, &block)
26
- if msg.key?(KEY)
27
- ::Cell::Tenant.use(::Cell::Tenant.cell_find(msg[KEY]), &block)
28
- else
29
- ::Cell::Tenant.use(nil, &block)
30
- end
31
-
32
- true
33
- end
34
- end
35
-
36
- module_function
37
- def configure!
38
- ::Sidekiq.configure_client do |config|
39
- config.client_middleware do |chain|
40
- chain.add ClientMiddleware
41
- end
42
- end
43
-
44
- ::Sidekiq.configure_server do |config|
45
- # The server can also act as a client by creating more jobs, so we
46
- # should configure the client inside the server block.
47
- config.client_middleware do |chain|
48
- chain.add ClientMiddleware
49
- end
50
-
51
- config.server_middleware do |chain|
52
- chain.add ServerMiddleware
53
- end
54
- end
55
-
56
- end
57
- end
58
- end
@@ -1,30 +0,0 @@
1
- require 'active_record/base'
2
-
3
- module Cell
4
- module WithSchema
5
- module_function
6
- def with_schema(new_path, exclusive: false, connection:)
7
- saved_path = connection.schema_search_path
8
- new_path = connection.quote_schema_name(new_path)
9
- active_path = exclusive ? new_path : "#{new_path},#{saved_path}"
10
-
11
- set_schema_search_path(active_path, connection: connection)
12
-
13
- if block_given?
14
- begin
15
- yield
16
- ensure
17
- set_schema_search_path(saved_path, connection: connection)
18
- end
19
- end
20
- end
21
-
22
- private \
23
- def set_schema_search_path(path, connection:)
24
- if path != connection.schema_search_path
25
- connection.schema_search_path = path
26
- connection.clear_query_cache
27
- end
28
- end
29
- end
30
- end
@@ -1,25 +0,0 @@
1
- # TenantRoutingManager contains methods that can locate URLs and such for
2
- # a given tenant.
3
-
4
- module TenantRoutingManager
5
- extend ActiveSupport::Concern
6
-
7
- class_methods do
8
- def slug_from_host(host)
9
- if host && (match = host.match(/\A([a-z][a-z0-9-]*)\./))
10
- return match[1]
11
- end
12
- return nil
13
- end
14
-
15
- def from_slug(slug)
16
- return friendly.find(slug)
17
- rescue ActiveRecord::RecordNotFound
18
- return nil
19
- end
20
-
21
- def from_host(host)
22
- from_slug(slug_from_host(host))
23
- end
24
- end
25
- end
@@ -1,17 +0,0 @@
1
- module TenantUrlOptions
2
- module_function \
3
- def default_url_options
4
- r = {}
5
- r[:protocol] = 'https' if Rails.env.production?
6
- r[:port] = 3000 unless Rails.env.production?
7
- r[:host] = Tenant.current.try(:host)
8
- r
9
- end
10
-
11
- end
12
-
13
- class ActionMailer::Base
14
- def default_url_options
15
- TenantUrlOptions.default_url_options
16
- end
17
- end