pelican 0.0.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/.gitignore +2 -0
- data/.ruby-gemset +1 -0
- data/.ruby-version +1 -0
- data/Gemfile +3 -0
- data/Gemfile.lock +19 -0
- data/LICENSE.txt +22 -0
- data/Rakefile +9 -0
- data/Readme.md +51 -0
- data/lib/pelican.rb +7 -0
- data/lib/pelican/config.rb +14 -0
- data/lib/pelican/event.rb +60 -0
- data/lib/pelican/version.rb +3 -0
- data/pelican.gemspec +21 -0
- data/test/test_helper.rb +13 -0
- data/test/unit/test_event.rb +39 -0
- metadata +104 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: 888a40fb4bb8c2b7f792e6bb2f8c1b4ce80cd97e
|
4
|
+
data.tar.gz: 21665d8b06ed665561ae9bbcdca2b2db54bbc4ec
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 32407a6599efaf7394a3dbcd5259bcdd9718d981ad105d493caeaa2dd6798798517841d0b4b573ba9e6a328c84966434c84ce2dbe5e0dfeca833c7a68cdcabf8
|
7
|
+
data.tar.gz: a83d035689bc8431b4189147d04f9a5a5db7e3ccd7980dfbbf782c5ddd9f4ad054b6ac8400baae70e1246cd17342eef4e238a8cfbc00cc5a53a0259b8197aa57
|
data/.gitignore
ADDED
data/.ruby-gemset
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
pelican
|
data/.ruby-version
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
ruby-2.1.0
|
data/Gemfile
ADDED
data/Gemfile.lock
ADDED
data/LICENSE.txt
ADDED
@@ -0,0 +1,22 @@
|
|
1
|
+
Copyright (c) 2012 Daniel Padden
|
2
|
+
|
3
|
+
MIT License
|
4
|
+
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
6
|
+
a copy of this software and associated documentation files (the
|
7
|
+
"Software"), to deal in the Software without restriction, including
|
8
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
9
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
10
|
+
permit persons to whom the Software is furnished to do so, subject to
|
11
|
+
the following conditions:
|
12
|
+
|
13
|
+
The above copyright notice and this permission notice shall be
|
14
|
+
included in all copies or substantial portions of the Software.
|
15
|
+
|
16
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
17
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
18
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
19
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
20
|
+
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
21
|
+
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
22
|
+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/Rakefile
ADDED
data/Readme.md
ADDED
@@ -0,0 +1,51 @@
|
|
1
|
+
# Pelican
|
2
|
+
|
3
|
+
Pelican stores the final state of modified objects. You can request a list of objects which were modified when compared to the last time you saw them, which provides a fast way of syncing states of objects across systems. When objects are modified multiple times, the history of those modifications are lost and only the final state is preserved. Pelican is ideal when only the final state of an object is important, so the history of modifications can be overwritten, which minimises disk space consumption and improves sync speed.
|
4
|
+
|
5
|
+
Curently Pelican stores objects using Redis. This is a quick lightweight database, which is easily scalable to millions of objects.
|
6
|
+
|
7
|
+
## Installation
|
8
|
+
|
9
|
+
You will need to have Redis installed. You can find this from http://redis.io/download
|
10
|
+
|
11
|
+
Then it is easy to install Pelican.
|
12
|
+
|
13
|
+
gem install pelican
|
14
|
+
|
15
|
+
You will need to configure Redis for Pelican
|
16
|
+
|
17
|
+
Pelican.setup(indexing_key, redis_config)
|
18
|
+
|
19
|
+
Pelican uses any standard Redis config, so you can set up Redis in your usual way.
|
20
|
+
|
21
|
+
e.g.
|
22
|
+
|
23
|
+
Pelican.setup(
|
24
|
+
'pelican:state',
|
25
|
+
host: 'localhost',
|
26
|
+
port: 6379,
|
27
|
+
db: 1)
|
28
|
+
|
29
|
+
Then just require Pelican when you need it
|
30
|
+
|
31
|
+
require 'pelican'
|
32
|
+
|
33
|
+
The order in which objects are stored is determined by a score. When an object is added or updated, it is given a score. The order of most modified objects is preserved by incrementing the score for each new modified score.
|
34
|
+
|
35
|
+
## Insert Objects
|
36
|
+
|
37
|
+
To insert or update an object with its current state, just use
|
38
|
+
|
39
|
+
Pelican::Event.insert('object1', 'state1')
|
40
|
+
|
41
|
+
## Listing objects
|
42
|
+
|
43
|
+
You can list all the modified objects from the last known score
|
44
|
+
|
45
|
+
current_score = Pelican::Event.list(last_score) { |object|
|
46
|
+
puts "current object: #{object}"
|
47
|
+
}
|
48
|
+
|
49
|
+
## Run Tests
|
50
|
+
|
51
|
+
rake test
|
data/lib/pelican.rb
ADDED
@@ -0,0 +1,60 @@
|
|
1
|
+
module Pelican
|
2
|
+
module Event
|
3
|
+
extend self
|
4
|
+
|
5
|
+
def insert(id, state)
|
6
|
+
begin
|
7
|
+
Pelican.redis.multi do
|
8
|
+
Pelican.redis.set(pelican_id(id), state)
|
9
|
+
end
|
10
|
+
update_event_list(pelican_id(id))
|
11
|
+
end
|
12
|
+
end
|
13
|
+
|
14
|
+
def delete(id)
|
15
|
+
begin
|
16
|
+
Pelican.redis.multi do
|
17
|
+
Pelican.redis.zrem(Pelican.key, pelican_id(id))
|
18
|
+
Pelican.del(pelican_id(id))
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
def list(last_score = 0)
|
24
|
+
max_score = last_score
|
25
|
+
last_score = '(' + last_score.to_s # make the search on last score exclusive
|
26
|
+
Pelican.redis.zrangebyscore(Pelican.key, last_score, '+inf', { withscores: true }).each do |id|
|
27
|
+
yield Pelican.redis.get(id[0])
|
28
|
+
max_score = id[1]
|
29
|
+
end
|
30
|
+
max_score
|
31
|
+
end
|
32
|
+
|
33
|
+
def pelican_id(id)
|
34
|
+
['pelican', id].join(':')
|
35
|
+
end
|
36
|
+
|
37
|
+
private
|
38
|
+
|
39
|
+
def update_event_list(id)
|
40
|
+
with_max_score do |max_score|
|
41
|
+
Pelican.redis.multi do
|
42
|
+
Pelican.redis.zadd(Pelican.key, max_score + 1, id)
|
43
|
+
end
|
44
|
+
end
|
45
|
+
end
|
46
|
+
|
47
|
+
def with_max_score
|
48
|
+
begin
|
49
|
+
Pelican.redis.watch(Pelican.key)
|
50
|
+
last_object = Pelican.redis.zrange(Pelican.key, -1, -1, { withscores: true })[0]
|
51
|
+
yield last_object.nil? ? 0 : last_object[1]
|
52
|
+
rescue => e
|
53
|
+
raise e
|
54
|
+
ensure
|
55
|
+
Pelican.redis.watch(Pelican.key)
|
56
|
+
end
|
57
|
+
end
|
58
|
+
|
59
|
+
end
|
60
|
+
end
|
data/pelican.gemspec
ADDED
@@ -0,0 +1,21 @@
|
|
1
|
+
require File.expand_path(File.join(File.dirname(__FILE__), 'lib', 'pelican', 'version'))
|
2
|
+
|
3
|
+
Gem::Specification.new do |gem|
|
4
|
+
gem.name = 'pelican'
|
5
|
+
gem.version = Pelican::VERSION
|
6
|
+
gem.authors = ['Daniel Padden']
|
7
|
+
gem.email = ['daniel.padden@forward3d.com']
|
8
|
+
gem.description = %q{Monitoring states of modified objects}
|
9
|
+
gem.summary = %q{Track changes to the state of an object and list all objects since a previous known state}
|
10
|
+
gem.homepage = 'https://github.com/hypernova2002/pelican'
|
11
|
+
gem.license = 'MIT'
|
12
|
+
|
13
|
+
gem.files = `git ls-files -z`.split("\x0")
|
14
|
+
gem.executables = gem.files.grep(%r{^bin/}) { |f| File.basename(f) }
|
15
|
+
gem.test_files = gem.files.grep(%r{^(test|spec|features)/})
|
16
|
+
gem.require_paths = ['lib']
|
17
|
+
|
18
|
+
gem.add_dependency 'redis', '~> 3.0'
|
19
|
+
gem.add_development_dependency 'bundler', '~> 1.3'
|
20
|
+
gem.add_development_dependency 'rake', '10.1.0'
|
21
|
+
end
|
data/test/test_helper.rb
ADDED
@@ -0,0 +1,13 @@
|
|
1
|
+
require 'test/unit'
|
2
|
+
require 'bundler'
|
3
|
+
Bundler.require
|
4
|
+
|
5
|
+
ROOT = File.dirname(File.dirname(File.expand_path(__FILE__)))
|
6
|
+
|
7
|
+
require File.join(ROOT, 'lib', 'pelican')
|
8
|
+
|
9
|
+
Pelican.setup(
|
10
|
+
'pelican_test:state',
|
11
|
+
host: 'localhost',
|
12
|
+
port: 6379,
|
13
|
+
db: 1)
|
@@ -0,0 +1,39 @@
|
|
1
|
+
require_relative File.join('..', 'test_helper')
|
2
|
+
|
3
|
+
class TestEvent < Test::Unit::TestCase
|
4
|
+
|
5
|
+
def setup
|
6
|
+
@objects = {'test_1' => 'state_1','test_2' => 'state_2','test_3' => 'state_3'}
|
7
|
+
clean_up!
|
8
|
+
|
9
|
+
at_exit do
|
10
|
+
unless @clean_up
|
11
|
+
clean_up!
|
12
|
+
end
|
13
|
+
end
|
14
|
+
end
|
15
|
+
|
16
|
+
def test_insert
|
17
|
+
@objects.each do |(key, state)|
|
18
|
+
Pelican::Event.insert(key, state)
|
19
|
+
end
|
20
|
+
|
21
|
+
@objects.each_with_index do |(key, state), index|
|
22
|
+
assert_equal index + 1, Pelican.redis.zscore(Pelican.key, Pelican::Event.pelican_id(key))
|
23
|
+
assert_equal state, Pelican.redis.get(Pelican::Event.pelican_id(key))
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
def clean_up!
|
28
|
+
@objects.each do |(key, state)|
|
29
|
+
Pelican.redis.del(Pelican::Event.pelican_id(key))
|
30
|
+
Pelican.redis.del(Pelican.key)
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
def teardown
|
35
|
+
clean_up!
|
36
|
+
@clean_up = true
|
37
|
+
end
|
38
|
+
|
39
|
+
end
|
metadata
ADDED
@@ -0,0 +1,104 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: pelican
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.0.1
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Daniel Padden
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
date: 2014-02-09 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: redis
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - "~>"
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: '3.0'
|
20
|
+
type: :runtime
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - "~>"
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: '3.0'
|
27
|
+
- !ruby/object:Gem::Dependency
|
28
|
+
name: bundler
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - "~>"
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: '1.3'
|
34
|
+
type: :development
|
35
|
+
prerelease: false
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
37
|
+
requirements:
|
38
|
+
- - "~>"
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: '1.3'
|
41
|
+
- !ruby/object:Gem::Dependency
|
42
|
+
name: rake
|
43
|
+
requirement: !ruby/object:Gem::Requirement
|
44
|
+
requirements:
|
45
|
+
- - '='
|
46
|
+
- !ruby/object:Gem::Version
|
47
|
+
version: 10.1.0
|
48
|
+
type: :development
|
49
|
+
prerelease: false
|
50
|
+
version_requirements: !ruby/object:Gem::Requirement
|
51
|
+
requirements:
|
52
|
+
- - '='
|
53
|
+
- !ruby/object:Gem::Version
|
54
|
+
version: 10.1.0
|
55
|
+
description: Monitoring states of modified objects
|
56
|
+
email:
|
57
|
+
- daniel.padden@forward3d.com
|
58
|
+
executables: []
|
59
|
+
extensions: []
|
60
|
+
extra_rdoc_files: []
|
61
|
+
files:
|
62
|
+
- ".gitignore"
|
63
|
+
- ".ruby-gemset"
|
64
|
+
- ".ruby-version"
|
65
|
+
- Gemfile
|
66
|
+
- Gemfile.lock
|
67
|
+
- LICENSE.txt
|
68
|
+
- Rakefile
|
69
|
+
- Readme.md
|
70
|
+
- lib/pelican.rb
|
71
|
+
- lib/pelican/config.rb
|
72
|
+
- lib/pelican/event.rb
|
73
|
+
- lib/pelican/version.rb
|
74
|
+
- pelican.gemspec
|
75
|
+
- test/test_helper.rb
|
76
|
+
- test/unit/test_event.rb
|
77
|
+
homepage: https://github.com/hypernova2002/pelican
|
78
|
+
licenses:
|
79
|
+
- MIT
|
80
|
+
metadata: {}
|
81
|
+
post_install_message:
|
82
|
+
rdoc_options: []
|
83
|
+
require_paths:
|
84
|
+
- lib
|
85
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
86
|
+
requirements:
|
87
|
+
- - ">="
|
88
|
+
- !ruby/object:Gem::Version
|
89
|
+
version: '0'
|
90
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
91
|
+
requirements:
|
92
|
+
- - ">="
|
93
|
+
- !ruby/object:Gem::Version
|
94
|
+
version: '0'
|
95
|
+
requirements: []
|
96
|
+
rubyforge_project:
|
97
|
+
rubygems_version: 2.2.2
|
98
|
+
signing_key:
|
99
|
+
specification_version: 4
|
100
|
+
summary: Track changes to the state of an object and list all objects since a previous
|
101
|
+
known state
|
102
|
+
test_files:
|
103
|
+
- test/test_helper.rb
|
104
|
+
- test/unit/test_event.rb
|