cell 0.1.1 → 0.1.2

Sign up to get free protection for your applications and to get access to all the features.
@@ -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