active_partition 0.4.0 → 0.6.0
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.
- checksums.yaml +4 -4
- data/Gemfile.lock +1 -1
- data/README.md +7 -0
- data/bin/console +26 -1
- data/lib/active_partition/partition_managers/time_range.rb +6 -2
- data/lib/active_partition/version.rb +1 -1
- data/lib/active_partition.rb +41 -35
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 942bdda1651b12d3dac2b0137a8d4ec024746bc6a494d7873d6328d1e5166ddc
|
4
|
+
data.tar.gz: 1f5770064c39d828a6d7fb4b7d89e4d1f49711bfb8fb304c8ad73430032e29f2
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 18119f845f143524abedfe280c09cfdd4cca5591a56aa4428413ee19cf3bb9f035e951ad3d1c7100a12e80fefc81037dc82f613b50b549497a1586ec655192b2
|
7
|
+
data.tar.gz: b56f0432c0c6fd7a42c8916547a97cd793be170e759f88b409ff9b2ec773f8a95c330997dfe111b4f37ac66137e52bd7ed3e105fdd547e8d5a92477ae3a78f2e
|
data/Gemfile.lock
CHANGED
data/README.md
CHANGED
@@ -38,6 +38,13 @@ class Event < ActiveRecord::Base
|
|
38
38
|
self.retention_period = 1.month
|
39
39
|
# Keep last n partitions
|
40
40
|
self.retention_partition_count = 3
|
41
|
+
# The start time of the partition range, default is Time.current.beginning_of_hour.utc
|
42
|
+
# For example, if today is July 31, and you create a new record.
|
43
|
+
# if the partition_start_from is 2021-01-01, the new partition should cover [2024-07-01 00:00:00 UTC...2024-08-01 00:00:00 UTC]
|
44
|
+
# if the partition_start_from is nil, the coverage can be [2024-07-31 08:00:00 UTC...2024-08-31 08:00:00 UTC]
|
45
|
+
# This configuration help us to sync partition ranges of all partitioned tables.
|
46
|
+
# Therefore, you can easy to join/drop/manage related partitioned tables.
|
47
|
+
self.partition_start_from = DateTime.new(2021, 1, 1)
|
41
48
|
end
|
42
49
|
|
43
50
|
# auto create a new partition if needed.
|
data/bin/console
CHANGED
@@ -5,7 +5,7 @@ require "bundler/setup"
|
|
5
5
|
require "active_partition"
|
6
6
|
require "active_record"
|
7
7
|
require "byebug"
|
8
|
-
|
8
|
+
require "rails"
|
9
9
|
def reload!
|
10
10
|
files = $LOADED_FEATURES.select { |feat| feat =~ /\/active_partition\// }
|
11
11
|
files.each { |file| load file }
|
@@ -30,7 +30,32 @@ class OutgoingEvent < ActiveRecord::Base
|
|
30
30
|
self.retention_partition_count = 3
|
31
31
|
end
|
32
32
|
|
33
|
+
class OutgoingEventsWebhook < ActiveRecord::Base
|
34
|
+
include ActivePartition::Partitionable
|
35
|
+
self.primary_key = "id"
|
36
|
+
self.partitioned_by = "created_at"
|
37
|
+
self.partition_range = 1.hour
|
38
|
+
self.partition_start_from = DateTime.new(2021, 1, 1)
|
39
|
+
|
40
|
+
# You can choose 1 of the following 2 options
|
41
|
+
self.retention_period = 1.day
|
42
|
+
self.retention_partition_count = 3
|
43
|
+
end
|
44
|
+
|
33
45
|
OutgoingEvent.establish_connection(ENV["DATABASE_URL"])
|
46
|
+
OutgoingEventsWebhook.establish_connection(ENV["DATABASE_URL"])
|
47
|
+
|
48
|
+
if OutgoingEventsWebhook.partition_adapter == OutgoingEvent.partition_adapter
|
49
|
+
puts "Violate the partition adapter constraint", OutgoingEventsWebhook.partition_adapter == OutgoingEvent.partition_adapter
|
50
|
+
puts OutgoingEventsWebhook.partition_adapter
|
51
|
+
puts OutgoingEvent.partition_adapter
|
52
|
+
end
|
53
|
+
|
54
|
+
if OutgoingEventsWebhook.partition_manager == OutgoingEvent.partition_manager
|
55
|
+
puts "Violate the partition manager constraint"
|
56
|
+
puts OutgoingEventsWebhook.partition_manager
|
57
|
+
puts OutgoingEvent.partition_manager
|
58
|
+
end
|
34
59
|
|
35
60
|
require "irb"
|
36
61
|
IRB.start(__FILE__)
|
@@ -2,9 +2,10 @@
|
|
2
2
|
|
3
3
|
module ActivePartition::PartitionManagers
|
4
4
|
class TimeRange
|
5
|
-
def initialize(partition_adapter, table_name)
|
5
|
+
def initialize(partition_adapter, table_name, partition_start_from = nil)
|
6
6
|
@partition_adapter = partition_adapter
|
7
7
|
@table_name = table_name
|
8
|
+
@partition_start_from = partition_start_from
|
8
9
|
end
|
9
10
|
|
10
11
|
# Retrieves the active ranges from the partition adapter.
|
@@ -15,6 +16,9 @@ module ActivePartition::PartitionManagers
|
|
15
16
|
#
|
16
17
|
# @return [Array] The array of active ranges.
|
17
18
|
def active_ranges
|
19
|
+
# in test environment, the partition table is not actually created. Therefore, return empty array
|
20
|
+
return [] if defined?(Rails) && Rails.env.test?
|
21
|
+
|
18
22
|
@active_ranges ||= reload_active_ranges(@partition_adapter.get_all_supported_partition_tables)
|
19
23
|
end
|
20
24
|
|
@@ -128,7 +132,7 @@ module ActivePartition::PartitionManagers
|
|
128
132
|
def latest_partition_coverage_time
|
129
133
|
partition_tables = @partition_adapter.get_all_supported_partition_tables
|
130
134
|
reload_active_ranges(partition_tables)
|
131
|
-
return Time.current.beginning_of_hour.utc if partition_tables.empty?
|
135
|
+
return (@partition_start_from || Time.current.beginning_of_hour.utc) if partition_tables.empty?
|
132
136
|
|
133
137
|
latest_partition_table = partition_tables.sort_by { |p_name| p_name.split("_").last.to_i }.last
|
134
138
|
@latest_coverage_at = Time.at(latest_partition_table.split("_").last.to_i).utc
|
data/lib/active_partition.rb
CHANGED
@@ -13,6 +13,7 @@ module ActivePartition
|
|
13
13
|
module Partitionable
|
14
14
|
extend ActiveSupport::Concern
|
15
15
|
|
16
|
+
# rubocop:disable Metrics
|
16
17
|
included do
|
17
18
|
# when partitioned column change, create partition if needed
|
18
19
|
# before_validation will be called with create, update, save, and create! methods
|
@@ -30,47 +31,52 @@ module ActivePartition
|
|
30
31
|
partitioned_value = attributes[self.class.partitioned_by.to_s]
|
31
32
|
self.class.prepare_partition(partitioned_value, self.class.partition_range)
|
32
33
|
end
|
33
|
-
end
|
34
|
-
|
35
|
-
# rubocop:disable Metrics
|
36
|
-
class_methods do
|
37
|
-
# The range of each partition. You can change this value over time.
|
38
|
-
# example: 1.month, 2.weeks, 3.hours
|
39
|
-
attr_accessor :partition_range
|
40
|
-
# The column name to partition the table by
|
41
|
-
attr_accessor :partitioned_by
|
42
|
-
# Retains partitions until the specified time [Choose one of retention_period or retention_partition_count]
|
43
|
-
# For example: 1.month (1 month from now), 2.weeks (2 weeks from now), 3.hours (3 hours from now)
|
44
|
-
attr_accessor :retention_period
|
45
|
-
# Retains the specified number of partitions [Choose one of retention_period or retention_partition_count]
|
46
|
-
attr_accessor :retention_partition_count
|
47
34
|
|
48
|
-
|
49
|
-
|
50
|
-
|
35
|
+
class << self
|
36
|
+
def partition_adapter
|
37
|
+
@partition_adapter ||= ActivePartition::Adapters::PostgresqlAdapter.new(connection, table_name)
|
38
|
+
end
|
51
39
|
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
40
|
+
def partition_manager
|
41
|
+
@partition_manager ||= case columns_hash[partitioned_by.to_s].type.to_s
|
42
|
+
when "datetime"
|
43
|
+
ActivePartition::PartitionManagers::TimeRange.new(partition_adapter, table_name, partition_start_from)
|
44
|
+
else
|
45
|
+
ActivePartition::PartitionManagers::TimeRange.new(partition_adapter, table_name, partition_start_from)
|
46
|
+
end
|
58
47
|
end
|
59
|
-
end
|
60
48
|
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
49
|
+
# The range of each partition. You can change this value over time.
|
50
|
+
# example: 1.month, 2.weeks, 3.hours
|
51
|
+
attr_accessor :partition_range
|
52
|
+
# The column name to partition the table by
|
53
|
+
attr_accessor :partitioned_by
|
54
|
+
# Retains partitions until the specified time [Choose one of retention_period or retention_partition_count]
|
55
|
+
# For example: 1.month (1 month from now), 2.weeks (2 weeks from now), 3.hours (3 hours from now)
|
56
|
+
attr_accessor :retention_period
|
57
|
+
# Retains the specified number of partitions [Choose one of retention_period or retention_partition_count]
|
58
|
+
attr_accessor :retention_partition_count
|
59
|
+
# The start time of the partition range, default is Time.current
|
60
|
+
attr_accessor :partition_start_from
|
61
|
+
|
62
|
+
def delete_expired_partitions
|
63
|
+
if retention_period && retention_period.is_a?(ActiveSupport::Duration)
|
64
|
+
partition_manager.retain_by_time(retention_period.ago)
|
65
|
+
elsif retention_partition_count
|
66
|
+
partition_manager.retain_by_partition_count(retention_partition_count)
|
67
|
+
end
|
66
68
|
end
|
67
|
-
end
|
68
69
|
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
|
70
|
+
delegate :premake, :latest_partition_coverage_time, to: :partition_manager
|
71
|
+
delegate :retain, :retain_by_time, :retain_by_partition_count, to: :partition_manager
|
72
|
+
delegate :prepare_partition, "active_partitions_cover?", to: :partition_manager
|
73
|
+
delegate :get_all_supported_partition_tables, to: :partition_adapter
|
74
|
+
delegate :drop_partition, to: :partition_adapter
|
75
|
+
end
|
74
76
|
end
|
77
|
+
|
78
|
+
# rubocop:disable Metrics
|
79
|
+
# class_methods do
|
80
|
+
# end
|
75
81
|
end
|
76
82
|
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: active_partition
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.6.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Thien Tran
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date: 2024-07-
|
11
|
+
date: 2024-07-31 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: byebug
|