lita-timing 0.1.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 ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 96f734b887a989426e7d3bfda449f1e050b164eb
4
+ data.tar.gz: 60797820ff5fb0aa13053a4da02a3bfdca2ef182
5
+ SHA512:
6
+ metadata.gz: 70952579da7d3d7ed7a09e90c495d8bf873517800269876894e92bfff7ada11ab3dc28e0115fc0d2c23905bd868e38db6567d882992e8e918abcc9181f0f5026
7
+ data.tar.gz: f054f0913f9cb4b957bc90801a8b2d30de070a11160d5e035ec5d0b52a2be4c8f91808448f4bda6d64601700d57519e51228b66e19bb5e6c12a8126f8d809b63
data/MIT-LICENSE ADDED
@@ -0,0 +1,20 @@
1
+ Copyright (c) 2016 James Healy
2
+
3
+ Permission is hereby granted, free of charge, to any person obtaining
4
+ a copy of this software and associated documentation files (the
5
+ "Software"), to deal in the Software without restriction, including
6
+ without limitation the rights to use, copy, modify, merge, publish,
7
+ distribute, sublicense, and/or sell copies of the Software, and to
8
+ permit persons to whom the Software is furnished to do so, subject to
9
+ the following conditions:
10
+
11
+ The above copyright notice and this permission notice shall be
12
+ included in all copies or substantial portions of the Software.
13
+
14
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
15
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
17
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
18
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
19
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
20
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,56 @@
1
+ # lita-timing
2
+
3
+ A small collection of utility classes that make it easier to work with time, recurring
4
+ events and rate limits in lita.
5
+
6
+ ## Installation
7
+
8
+ Add this gem to your lita installation by including the following line in your Gemfile:
9
+
10
+ gem "lita-timing"
11
+
12
+ ## Usage
13
+
14
+ This gem is not a lita handler or plugin in its own right, but it is easily used
15
+ by other lita plugins.
16
+
17
+ ### Rate Limits
18
+
19
+ lita comes with an "every" helper that executes a block of code at fixed
20
+ intervals. However the interval is only stored in memory, which means
21
+ long intervals will often be reset if the lita process restarts (like
22
+ during a deploy).
23
+
24
+ For handlers that want to execute code at fixed intervals, the RateLimit
25
+ class can be used in conjunction with the built in every() helper:
26
+
27
+ one_minute = 60
28
+ one_week = 60 + 60 + 24 + 7
29
+ every(one_minute) do
30
+ RateLimit.new("interval-name", redis).once_every(one_week) do
31
+ # weekly code in here
32
+ end
33
+ end
34
+
35
+ ### Sliding Windows
36
+
37
+ Sometimes a handler wants to periodically execute a block of code with a start
38
+ and end time, and ensure that every minute of the day is handled by one of the
39
+ executions. The text-book use case is polling an external API for updates within
40
+ a time range.
41
+
42
+ The SlidingWindow class can help. For best results, use it in conjunction with the
43
+ built in every() helper.
44
+
45
+ Redis is used to persist the end of the last window that executed and ensure the
46
+ block doesn't execute again until that window is passed.
47
+
48
+ window = SlidingWindow.new("my-sliding-window", redis)
49
+ every(one_minute) do
50
+ window.advance(duration_minutes: 30) do |window_start, window_end|
51
+ puts "#{window_start} -> #{window_end}"
52
+ end
53
+ end
54
+
55
+ Call this as often as you like, and the block passed to advance() will
56
+ only execute if it's been 30 minutes since the last time it executed.
@@ -0,0 +1,2 @@
1
+ require 'lita/timing/rate_limit'
2
+ require 'lita/timing/sliding_window'
@@ -0,0 +1,22 @@
1
+ module Lita
2
+ module Timing
3
+ class RateLimit
4
+ def initialize(name, redis)
5
+ @name, @redis = name, redis
6
+ end
7
+
8
+ def once_every(seconds, &block)
9
+ if last_time.nil? || last_time + seconds < Time.now
10
+ yield
11
+ @redis.set(@name, Time.now.to_i)
12
+ end
13
+ end
14
+
15
+ def last_time
16
+ value = @redis.get(@name)
17
+ value ? Time.at(value.to_i).utc : nil
18
+ end
19
+
20
+ end
21
+ end
22
+ end
@@ -0,0 +1,41 @@
1
+ module Lita
2
+ module Timing
3
+ class SlidingWindow
4
+ def initialize(name, redis)
5
+ @name, @redis = name, redis
6
+
7
+ initialise_last_time_if_not_set
8
+ end
9
+
10
+ def advance(duration_minutes: 30, buffer_minutes: 0, &block)
11
+ start_time = Time.now - mins_to_seconds(duration_minutes) - mins_to_seconds(buffer_minutes)
12
+ advance_to = start_time + mins_to_seconds(duration_minutes)
13
+
14
+ return unless start_time > last_time
15
+
16
+ yield last_time, advance_to
17
+
18
+ @redis.set(@name, advance_to.to_i)
19
+ end
20
+
21
+ private
22
+
23
+ def mins_to_seconds(mins)
24
+ mins * 60
25
+ end
26
+
27
+ def last_time
28
+ Time.at(@redis.get(@name).to_i)
29
+ end
30
+
31
+ def initialise_last_time_if_not_set
32
+ @redis.setnx(@name, two_weeks_ago.to_i)
33
+ end
34
+
35
+ def two_weeks_ago
36
+ ::Time.now - (60 * 60 * 24 * 14)
37
+ end
38
+
39
+ end
40
+ end
41
+ end
metadata ADDED
@@ -0,0 +1,107 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: lita-timing
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.0
5
+ platform: ruby
6
+ authors:
7
+ - James Healy
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2016-06-12 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: rake
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - ">="
18
+ - !ruby/object:Gem::Version
19
+ version: '0'
20
+ type: :development
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - ">="
25
+ - !ruby/object:Gem::Version
26
+ version: '0'
27
+ - !ruby/object:Gem::Dependency
28
+ name: rspec
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - "~>"
32
+ - !ruby/object:Gem::Version
33
+ version: '3.4'
34
+ type: :development
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - "~>"
39
+ - !ruby/object:Gem::Version
40
+ version: '3.4'
41
+ - !ruby/object:Gem::Dependency
42
+ name: pry
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - ">="
46
+ - !ruby/object:Gem::Version
47
+ version: '0'
48
+ type: :development
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - ">="
53
+ - !ruby/object:Gem::Version
54
+ version: '0'
55
+ - !ruby/object:Gem::Dependency
56
+ name: rdoc
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - ">="
60
+ - !ruby/object:Gem::Version
61
+ version: '0'
62
+ type: :development
63
+ prerelease: false
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - ">="
67
+ - !ruby/object:Gem::Version
68
+ version: '0'
69
+ description: Provides utilities that help with repeating tasks and rate limits
70
+ email:
71
+ - james.healy@theconversation.edu.au
72
+ executables: []
73
+ extensions: []
74
+ extra_rdoc_files:
75
+ - README.md
76
+ - MIT-LICENSE
77
+ files:
78
+ - MIT-LICENSE
79
+ - README.md
80
+ - lib/lita-timing.rb
81
+ - lib/lita/timing/rate_limit.rb
82
+ - lib/lita/timing/sliding_window.rb
83
+ homepage: http://github.com/yob/lita-timing
84
+ licenses:
85
+ - MIT
86
+ metadata: {}
87
+ post_install_message:
88
+ rdoc_options: []
89
+ require_paths:
90
+ - lib
91
+ required_ruby_version: !ruby/object:Gem::Requirement
92
+ requirements:
93
+ - - ">="
94
+ - !ruby/object:Gem::Version
95
+ version: 1.9.3
96
+ required_rubygems_version: !ruby/object:Gem::Requirement
97
+ requirements:
98
+ - - ">="
99
+ - !ruby/object:Gem::Version
100
+ version: '0'
101
+ requirements: []
102
+ rubyforge_project:
103
+ rubygems_version: 2.5.1
104
+ signing_key:
105
+ specification_version: 4
106
+ summary: Utilities for time related tasks in lita
107
+ test_files: []