piko_transaction 2.1.0 → 3.0.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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: e2a5c353c83ff13ddda8d02da3472d26817097f3
4
- data.tar.gz: bd2b2647b33ac8b31909d2362bc41c821280b8e2
3
+ metadata.gz: 1fb92d89b2652b73d375601b371f4e455bb288a2
4
+ data.tar.gz: 2aedbe5d5503fd358d82bc407a8f5f572d14c066
5
5
  SHA512:
6
- metadata.gz: 74bb0c9fd14f7feaf3cee6f36725a7e6ceb47a300ab822153c834c4bf994d4375775c9db875b26bb33c5022880ef78ef1ba8890b5ebfe816bac9fdcd05036518
7
- data.tar.gz: 54f72334b93ebe20e88f6ffe72ada7328f6f4c12f1923eae165aa7c4f33c667ea96c1b9ffbb910748d6b791bb9d2922d73dbd6e9974812a19ed76508fe817abc
6
+ metadata.gz: d007f9c884d25c6028e8e790239be5d2b2886970963d9df4b91cab56e0927dd4cab49f628d20cfb8675b988a92e457e5aa387b96f9be42ee3976f6745628f6af
7
+ data.tar.gz: 29a8c4244b32c2e9de4f03b724116bee83472b5bc2630391bd74e82eef1128a2f76f8393d365eecd588983c4cb9500e22cbfc43dd624470fe8ab3636e656a6b4
data/CHANGELOG.md CHANGED
@@ -1,3 +1,9 @@
1
+ ### 3.0.0 (2017.06.13)
2
+
3
+ * allow to register success and failure observers in commands
4
+ * commands and transactions have names
5
+ * improved logger
6
+
1
7
  ### 2.1.0 (2017.06.08)
2
8
 
3
9
  * add transaction holder class
@@ -24,30 +24,48 @@ module PikoTransaction
24
24
  include Logger
25
25
 
26
26
  def initialize(do_action = nil, undo_action = nil, &alternative_do_action)
27
- @do_action = do_action
27
+ @name = nil
28
+ @do_action = choose_do_action(do_action, alternative_do_action)
28
29
  @undo_action = undo_action
29
- @alternative_do_action = alternative_do_action
30
+ @success_callbacks = []
31
+ @failure_callbacks = []
30
32
  @done = false
31
33
  end
32
34
 
33
35
  def do
34
- return terminate("Command already done") unless can_do?
35
- return terminate("Can not execute 'do' action") unless execute_do_action
36
- mark_as_done
37
- true
36
+ execute_do_action ? call_success_callbacks : call_failure_callbacks
38
37
  end
39
38
 
40
39
  def undo
41
- return terminate("Can not undo command") unless can_undo?
42
- return terminate("Can not execute 'undo' action") unless execute_undo_action
43
- mark_as_undone
44
- true
40
+ execute_undo_action
41
+ end
42
+
43
+ def to_s
44
+ format "[%s]", @name || "custom_cmd"
45
+ end
46
+
47
+ def name(value)
48
+ @name = value.to_s
49
+ end
50
+
51
+ def add_success_callback(callback)
52
+ @success_callbacks << callback if callback.respond_to?(:call)
53
+ logger.debug { format "%s Registered success callbacks: %i", to_s, @success_callbacks.count }
54
+ end
55
+
56
+ def add_failure_callback(callback)
57
+ @failure_callbacks << callback if callback.respond_to?(:call)
58
+ logger.debug { format "%s Registered failure callbacks: %i", to_s, @failure_callbacks.count }
45
59
  end
46
60
 
47
61
  private
48
62
 
63
+ def choose_do_action(action, alternative_action)
64
+ action || alternative_action
65
+ end
66
+
49
67
  def terminate(msg)
50
- logger.warn { msg }
68
+ logger.warn { format "%s %s", to_s, msg }
51
69
  false
52
70
  end
53
71
 
@@ -57,6 +75,7 @@ module PikoTransaction
57
75
 
58
76
  def mark_as_undone
59
77
  @done = false
78
+ true
60
79
  end
61
80
 
62
81
  def can_do?
@@ -68,20 +87,60 @@ module PikoTransaction
68
87
  end
69
88
 
70
89
  def execute_do_action
71
- action = choose_do_action
72
- return terminate("Bad 'do' action") unless action.respond_to? :call
73
- logger.debug { "Executing do action" }
74
- action.call
90
+ return terminate("Command already done") unless can_do?
91
+ return terminate("'Do' action do not responds to :call") unless \
92
+ callable_action?(@do_action)
93
+ return terminate("'Do' action returns false") unless safe_call_do_action
94
+ mark_as_done
75
95
  end
76
96
 
77
- def choose_do_action
78
- @do_action || @alternative_do_action
97
+ def safe_call_do_action
98
+ logger.info { format "%s Executing custom 'do' action", to_s }
99
+ return safe_call_action(@do_action) unless @do_action.nil?
100
+ logger.warn { format "%s Nothing to 'do'", to_s }
101
+ true
102
+ end
103
+
104
+ def safe_call_action(action)
105
+ action.call ? true : false
106
+ rescue => e
107
+ logger.fatal { format "%s %s - %s", to_s, e.class.name, e.message }
108
+ false
109
+ end
110
+
111
+ def callable_action?(action)
112
+ action.nil? || action.respond_to?(:call)
79
113
  end
80
114
 
81
115
  def execute_undo_action
82
- return true unless @undo_action.respond_to? :call
83
- logger.debug { "Executing undo action" }
84
- @undo_action.call
116
+ return terminate("Can not undo command") unless can_undo?
117
+ return terminate("'Undo' action do not responds to :call") unless \
118
+ callable_action?(@undo_action)
119
+ return terminate("'Undo' action returns false") unless safe_call_undo_action
120
+ mark_as_undone
121
+ end
122
+
123
+ def safe_call_undo_action
124
+ logger.debug { format "%s Executing custom 'undo' action", to_s }
125
+ return safe_call_action(@undo_action) unless @undo_action.nil?
126
+ logger.warn { format "%s Nothing to 'undo'", to_s }
127
+ true
128
+ end
129
+
130
+ def call_success_callbacks
131
+ @success_callbacks.each_with_index do |callback, i|
132
+ logger.debug { format "%s Run %i success callback", to_s, i + 1 }
133
+ callback.call
134
+ end
135
+ true
136
+ end
137
+
138
+ def call_failure_callbacks
139
+ @failure_callbacks.each_with_index do |callback, i|
140
+ logger.debug { format "%s Run %i failure callback", to_s, i + 1 }
141
+ callback.call
142
+ end
143
+ false
85
144
  end
86
145
  end
87
146
  end
@@ -24,32 +24,47 @@ module PikoTransaction
24
24
  include Logger
25
25
 
26
26
  def initialize(document_id, collection, &success_action)
27
+ @name = nil
27
28
  @document_id = document_id
28
29
  @collection = collection
29
30
  @success_action = success_action
31
+ @success_callbacks = []
32
+ @failure_callbacks = []
30
33
  @deleted_doc = nil
31
34
  @done = false
32
35
  end
33
36
 
34
37
  def do
35
- return terminate("Command already done") unless can_do?
36
- return terminate("Can not delete document") unless remove_document
37
- call_success_action
38
- mark_as_done
39
- true
38
+ add_success_callback @success_action
39
+ remove_document ? call_success_callbacks : call_failure_callbacks
40
40
  end
41
41
 
42
42
  def undo
43
- return terminate("Can not undo command") unless can_undo?
44
- return terminate("Can not restore document") unless store_document
45
- mark_as_undone
46
- true
43
+ store_document
44
+ end
45
+
46
+ def to_s
47
+ format "[%s]", @name || "delete_cmd"
48
+ end
49
+
50
+ def name(value)
51
+ @name = value.to_s
52
+ end
53
+
54
+ def add_success_callback(callback)
55
+ @success_callbacks << callback if callback.respond_to?(:call)
56
+ logger.debug { format "%s Registered success callbacks: %s", to_s, @success_callbacks.count }
57
+ end
58
+
59
+ def add_failure_callback(callback)
60
+ @failure_callbacks << callback if callback.respond_to?(:call)
61
+ logger.debug { format "%s Registered failure callbacks: %s", to_s, @failure_callbacks.count }
47
62
  end
48
63
 
49
64
  private
50
65
 
51
66
  def terminate(msg)
52
- logger.warn { msg }
67
+ logger.warn { format "%s %s", to_s, msg }
53
68
  false
54
69
  end
55
70
 
@@ -59,6 +74,7 @@ module PikoTransaction
59
74
 
60
75
  def mark_as_undone
61
76
  @done = false
77
+ true
62
78
  end
63
79
 
64
80
  def can_do?
@@ -70,19 +86,43 @@ module PikoTransaction
70
86
  end
71
87
 
72
88
  def remove_document
73
- logger.info { format "Doing command with %s", @document_id }
89
+ return terminate("Command already done") unless can_do?
90
+ return terminate("Error during deleting document") unless delete_document_from_collection
91
+ mark_as_done
92
+ end
93
+
94
+ def delete_document_from_collection
95
+ logger.info do
96
+ format "%s Deleting document '%s' from '%s'", to_s, @document_id, @collection.to_s
97
+ end
74
98
  @collection.find_and_delete_document(@document_id) { |doc| @deleted_doc = doc }
75
99
  end
76
100
 
77
101
  def store_document
78
- logger.info { format "Restoring document: %s", @deleted_doc }
102
+ return terminate("Can not undo without do") unless can_undo?
103
+ return terminate("Error durind restoring document") unless insert_document_into_collection
104
+ mark_as_undone
105
+ end
106
+
107
+ def insert_document_into_collection
108
+ logger.info { format "%s Restoring document %s in %s", to_s, @deleted_doc, @collection.to_s }
79
109
  @collection.insert_document(@deleted_doc)
80
110
  end
81
111
 
82
- def call_success_action
83
- return unless @success_action.is_a?(Proc)
84
- logger.debug { format "Executting callback with: %s", @deleted_doc }
85
- @success_action.call(@deleted_doc)
112
+ def call_success_callbacks
113
+ @success_callbacks.each_with_index do |callback, i|
114
+ logger.debug { format "%s Run %i success callback with: %s", to_s, i + 1, @deleted_doc }
115
+ callback.call(@deleted_doc)
116
+ end
117
+ true
118
+ end
119
+
120
+ def call_failure_callbacks
121
+ @failure_callbacks.each_with_index do |callback, i|
122
+ logger.debug { format "%s Run %i failure callback", to_s, i + 1 }
123
+ callback.call
124
+ end
125
+ false
86
126
  end
87
127
  end
88
128
  end
@@ -24,32 +24,47 @@ module PikoTransaction
24
24
  include Logger
25
25
 
26
26
  def initialize(document, collection, &success_action)
27
+ @name = nil
27
28
  @document = document
28
29
  @collection = collection
29
30
  @success_action = success_action
31
+ @success_callbacks = []
32
+ @failure_callbacks = []
30
33
  @inserted_id = nil
31
34
  @done = false
32
35
  end
33
36
 
34
37
  def do
35
- return terminate("Command already done") unless can_do?
36
- return terminate("Can not store document") unless store_document
37
- call_success_action
38
- mark_as_done
39
- true
38
+ add_success_callback @success_action
39
+ store_document ? call_success_callbacks : call_failure_callbacks
40
40
  end
41
41
 
42
42
  def undo
43
- return terminate("Can not undo command") unless can_undo?
44
- return terminate("Can not delete document") unless remove_document
45
- mark_as_undone
46
- true
43
+ remove_document
44
+ end
45
+
46
+ def to_s
47
+ format "[%s]", @name || "insert_cmd"
48
+ end
49
+
50
+ def name(value)
51
+ @name = value.to_s
52
+ end
53
+
54
+ def add_success_callback(callback)
55
+ @success_callbacks << callback if callback.respond_to?(:call)
56
+ logger.debug { format "%s Registered success callbacks: %i", to_s, @success_callbacks.count }
57
+ end
58
+
59
+ def add_failure_callback(callback)
60
+ @failure_callbacks << callback if callback.respond_to?(:call)
61
+ logger.debug { format "%s Registered failure callbacks: %i", to_s, @failure_callbacks.count }
47
62
  end
48
63
 
49
64
  private
50
65
 
51
66
  def terminate(msg)
52
- logger.warn { msg }
67
+ logger.warn { format "%s %s", to_s, msg }
53
68
  false
54
69
  end
55
70
 
@@ -59,6 +74,7 @@ module PikoTransaction
59
74
 
60
75
  def mark_as_undone
61
76
  @done = false
77
+ true
62
78
  end
63
79
 
64
80
  def can_do?
@@ -70,19 +86,43 @@ module PikoTransaction
70
86
  end
71
87
 
72
88
  def store_document
73
- logger.info { format "Inserting %s into '%s'", @document, @collection.to_s }
89
+ return terminate("Command already done") unless can_do?
90
+ return terminate("Error during inserting document") unless insert_document_into_collection
91
+ mark_as_done
92
+ end
93
+
94
+ def insert_document_into_collection
95
+ logger.info { format "%s Inserting %s into '%s'", to_s, @document, @collection.to_s }
74
96
  @collection.insert_document(@document) { |doc_id| @inserted_id = doc_id }
75
97
  end
76
98
 
77
99
  def remove_document
78
- logger.info { format "Undoing command for document: %s", @inserted_id }
100
+ return terminate("Can not undo without do") unless can_undo?
101
+ return terminate("Error during withdrawing document") unless delete_document_from_collection
102
+ mark_as_undone
103
+ end
104
+
105
+ def delete_document_from_collection
106
+ logger.info do
107
+ format "%s Withdrawing document '%s' from '%s'", to_s, @inserted_id, @collection.to_s
108
+ end
79
109
  @collection.delete_document(@inserted_id)
80
110
  end
81
111
 
82
- def call_success_action
83
- return unless @success_action.is_a?(Proc)
84
- logger.debug { format "Executting callback with: %s", @inserted_id }
85
- @success_action.call(@inserted_id)
112
+ def call_success_callbacks
113
+ @success_callbacks.each_with_index do |callback, i|
114
+ logger.debug { format "%s Run %i success callback with: %s", to_s, i + 1, @inserted_id }
115
+ callback.call(@inserted_id)
116
+ end
117
+ true
118
+ end
119
+
120
+ def call_failure_callbacks
121
+ @failure_callbacks.each_with_index do |callback, i|
122
+ logger.debug { format "%s Run %i failure callback", to_s, i + 1 }
123
+ callback.call
124
+ end
125
+ false
86
126
  end
87
127
  end
88
128
  end
@@ -23,41 +23,47 @@ module PikoTransaction
23
23
  class Transaction
24
24
  include Logger
25
25
 
26
- def initialize
26
+ def initialize(name = nil)
27
+ @name = name
27
28
  @commands = []
28
29
  @done = []
29
30
  yield self if block_given?
30
31
  end
31
32
 
32
33
  def add(command)
33
- logger.debug { format "Add command: %s", command.class.name }
34
34
  @commands << command
35
+ logger.debug do
36
+ format "%s Added command: %s, total: %i", to_s, command.to_s, @commands.count
37
+ end
35
38
  end
36
39
 
37
40
  def do
38
- logger.info { format "Start transaction with commands: %s", @commands.count }
41
+ logger.info { format "%s Start transaction with commands: %s", to_s, @commands.count }
39
42
  return true if run_commands
40
43
  terminate_and_undo
41
44
  end
42
45
 
43
46
  def undo
44
- logger.info { format "Rolling back transaction with commands: %s", @done.count }
47
+ logger.info { format "%s Rolling back transaction with commands: %s", to_s, @done.count }
45
48
  undo_done_commands
46
49
  end
47
50
 
51
+ def to_s
52
+ format "[%s]", @name || "tr"
53
+ end
54
+
48
55
  private
49
56
 
50
57
  def terminate_and_undo
51
- logger.error { "Could not finalize transaction!" }
58
+ logger.error { format "%s Could not finalize transaction!", to_s }
52
59
  undo_done_commands
53
60
  false
54
61
  end
55
62
 
56
63
  def run_commands
57
- @commands.each do |cmd|
58
- logger.debug { format "Do: %s", cmd.class.name }
59
- unless cmd.do
60
- logger.error { "Command execution failed" }
64
+ @commands.each_with_index do |cmd, i|
65
+ unless doing_command(cmd, i)
66
+ logger.warn { format "%s Command %s failed", to_s, cmd.to_s }
61
67
  return false
62
68
  end
63
69
  @done << cmd
@@ -65,14 +71,24 @@ module PikoTransaction
65
71
  true
66
72
  end
67
73
 
74
+ def doing_command(cmd, i)
75
+ logger.debug { format "%s Running %i command: %s", to_s, i + 1, cmd.to_s }
76
+ cmd.do
77
+ end
78
+
68
79
  def undo_done_commands
69
- @done.reverse.each do |cmd|
70
- logger.debug { format "Undo: %s", cmd.class.name }
71
- unless cmd.undo
72
- logger.fatal { "Can not undo command" }
80
+ @done.each_with_index.reverse_each do |cmd, i|
81
+ unless undoing_command(cmd, i)
82
+ logger.fatal { format "%s Can not undo command: %s", to_s, cmd.to_s }
73
83
  break
74
84
  end
85
+ @done.delete(cmd)
75
86
  end
76
87
  end
88
+
89
+ def undoing_command(cmd, i)
90
+ logger.debug { format "%s Undoing %i command: %s", to_s, i + 1, cmd.to_s }
91
+ cmd.undo
92
+ end
77
93
  end
78
94
  end
@@ -31,7 +31,7 @@ module PikoTransaction
31
31
  def method_missing(method_name, *args, &block)
32
32
  logger.debug { format "Looking for transaction '%s'", method_name }
33
33
  return super unless valid_method_name?(method_name)
34
- @transactions[method_name] ||= Transaction.new
34
+ @transactions[method_name] ||= Transaction.new method_name
35
35
  end
36
36
 
37
37
  private
@@ -18,5 +18,5 @@
18
18
  # along with this program. If not, see <http://www.gnu.org/licenses/>.
19
19
 
20
20
  module PikoTransaction
21
- VERSION = "2.1.0"
21
+ VERSION = "3.0.0"
22
22
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: piko_transaction
3
3
  version: !ruby/object:Gem::Version
4
- version: 2.1.0
4
+ version: 3.0.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Szymon Kopciewski
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2017-06-08 00:00:00.000000000 Z
11
+ date: 2017-06-13 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: logger2r