pelican 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
@@ -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
@@ -0,0 +1,2 @@
1
+ pelican-*.gem
2
+ .bundle
@@ -0,0 +1 @@
1
+ pelican
@@ -0,0 +1 @@
1
+ ruby-2.1.0
data/Gemfile ADDED
@@ -0,0 +1,3 @@
1
+ source 'https://rubygems.org'
2
+
3
+ gemspec
@@ -0,0 +1,19 @@
1
+ PATH
2
+ remote: .
3
+ specs:
4
+ pelican (0.0.1)
5
+ redis (~> 3.0)
6
+
7
+ GEM
8
+ remote: https://rubygems.org/
9
+ specs:
10
+ rake (10.1.0)
11
+ redis (3.0.7)
12
+
13
+ PLATFORMS
14
+ ruby
15
+
16
+ DEPENDENCIES
17
+ bundler (~> 1.3)
18
+ pelican!
19
+ rake (= 10.1.0)
@@ -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.
@@ -0,0 +1,9 @@
1
+ require "bundler/setup"
2
+ require "bundler/gem_tasks"
3
+ require 'rake/testtask'
4
+
5
+ Rake::TestTask.new do |t|
6
+ t.libs << "test"
7
+ t.test_files = FileList['test/**/test*.rb']
8
+ t.verbose = true
9
+ end
@@ -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
@@ -0,0 +1,7 @@
1
+ require 'securerandom'
2
+ require 'redis'
3
+ require_relative 'pelican/config'
4
+ require_relative 'pelican/event'
5
+
6
+ module Pelican
7
+ end
@@ -0,0 +1,14 @@
1
+ module Pelican
2
+ extend self
3
+ attr_accessor :redis, :key
4
+
5
+ def setup(key = nil, opts = {})
6
+ @key = key || default_key
7
+ @redis = Redis.new(opts)
8
+ end
9
+
10
+ def default_key
11
+ 'pelican:state'
12
+ end
13
+
14
+ end
@@ -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
@@ -0,0 +1,3 @@
1
+ module Pelican
2
+ VERSION = '0.0.1'
3
+ end
@@ -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
@@ -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