simple_stats_store 1.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 ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 03dc5993bc4a5e7ec010d5601add13295a9d3cfc
4
+ data.tar.gz: cfe61488fb2db2b0a2562515ee6efc2fcde61501
5
+ SHA512:
6
+ metadata.gz: 4bb37b8ff0d17d9d5bac6258bc6af92a840ba68dda73e3f50d45a247a10d37e5b27e13d885910e3fe51379c3b51a00975113cdf07401ae8776ae90ba0063f382
7
+ data.tar.gz: fd35eec5a1d2904de47e6da818ab395b16b887b605506d05e4d27a10d48a7e9cb4868a007dbca4bc9c1427300446363b3a77308472c2cdae4c1d64354b9b1a32
data/README.md ADDED
@@ -0,0 +1,89 @@
1
+ # Simple Stats Store
2
+
3
+ ## Introduction
4
+
5
+ The purpose of Simple Stats Store is to provide a simple and lightweight method
6
+ for multiple processes to dump data into an SQLite database without contention.
7
+
8
+ It is appropriate to be used when:
9
+
10
+ * There are multiple threads or processes submitting statistics
11
+ * Data concurrency is less important than avoiding waiting on database locks
12
+
13
+ This is achieved by the threads dropping uniquely named files into a common
14
+ directory containing the statistics which are then picked up by a single thread
15
+ that is the sole accessor of the database.
16
+
17
+ ## Usage
18
+
19
+ ### General
20
+
21
+ Create the repository for temporary data files:
22
+
23
+ ```ruby
24
+ require 'simple_stats_store/file_dump'
25
+
26
+ dir = '/path/to/temporary/data/directory'
27
+ Dir.mkdir(dir)
28
+ data_dump = SimpleStatsStore::FileDump.new(dir)
29
+ ```
30
+
31
+ ### Server
32
+
33
+ Set up the database:
34
+
35
+ ```ruby
36
+ require 'simple_stats_store/server'
37
+
38
+ db_file = '/path/to/database.sql'
39
+ ActiveRecord::Base.establish_connection(
40
+ adapter: :sqlite3,
41
+ database: db_file
42
+ )
43
+ ActiveRecord::Schema.define do
44
+ create_table :table do |table|
45
+ table.column :timestamp, :string
46
+ table.column :key_1, :integer
47
+ table.column :key_2, :float
48
+ # etc.
49
+ end
50
+ end
51
+ class Table < ActiveRecord::Base
52
+ end
53
+
54
+ ssss = SimpleStatsStore::Server.new(
55
+ data_dump: data_dump,
56
+ models: { table_ref: Table }
57
+ )
58
+
59
+ t_next = Time.new + 300
60
+ server_pid = ssss.run do
61
+ if Time.new >= t_next
62
+ # Code to be executed every 5 minutes
63
+ # ...
64
+ t_next += 300
65
+ end
66
+ end
67
+ ```
68
+
69
+ ### Client
70
+
71
+ Write data
72
+
73
+ ```ruby
74
+ data_dump.write(
75
+ table_ref,
76
+ {
77
+ timestamp: Time.new.to_s,
78
+ key_1: value_1,
79
+ key_2: value_2,
80
+ # etc.
81
+ }
82
+ )
83
+ ```
84
+
85
+ ## License
86
+
87
+ Simple Stats Store is available to everyone under the terms of the MIT open source licence. Take a look at the LICENSE file in the code.
88
+
89
+ Copyright (c) 2015 BBC
@@ -0,0 +1,5 @@
1
+ require 'simple_stats_store/server'
2
+ require 'simple_stats_store/file_dump'
3
+
4
+ module SimpleStatsStore
5
+ end
@@ -0,0 +1,40 @@
1
+ require 'tempfile'
2
+
3
+ module SimpleStatsStore
4
+ class FileDump
5
+ def initialize(dir)
6
+ @dir = dir
7
+ end
8
+
9
+ def files_contents
10
+ contents = []
11
+ Dir["#{@dir}/*"].each do |f|
12
+ data = File.open(f, 'r').read
13
+ if /\n---\n$/.match(data)
14
+ contents << data
15
+ File.delete(f)
16
+ end
17
+ end
18
+ contents
19
+ end
20
+
21
+ def each(&block)
22
+ files_contents.each &block
23
+ end
24
+
25
+ def write(model, data)
26
+ i = 0
27
+ while File.exists?(File.expand_path("sss-#{$$}-#{Time.new.to_i}-#{i}.stats", @dir))
28
+ i += 1
29
+ end
30
+ File.open(File.expand_path("sss-#{$$}-#{Time.new.to_i}-#{i}.stats", @dir), 'w') do |f|
31
+ f.puts "---"
32
+ f.puts model
33
+ data.each do |key, value|
34
+ f.puts "#{key.to_s}: #{value}"
35
+ end
36
+ f.puts "---"
37
+ end
38
+ end
39
+ end
40
+ end
@@ -0,0 +1,7 @@
1
+ module SimpleStatsStore
2
+ class NilDump
3
+ def each(&block)
4
+ [].each(&block)
5
+ end
6
+ end
7
+ end
@@ -0,0 +1,37 @@
1
+ module SimpleStatsStore
2
+ class Server
3
+ def initialize(options)
4
+ @data_dump = options[:data_dump]
5
+ @models = options[:models]
6
+ end
7
+
8
+ def scan
9
+ @data_dump.each do |stats|
10
+ lines = stats.split("\n")
11
+ if lines.shift != '---' or lines.pop != '---'
12
+ puts "Corrupt statistics"
13
+ return false
14
+ end
15
+
16
+ model = lines.shift.strip
17
+ data = {}
18
+ lines.each do |l|
19
+ k, v = l.split(/:/, 2)
20
+ data[k.strip.to_sym] = v.strip
21
+ end
22
+
23
+ @models[model.to_sym].create(data)
24
+ end
25
+ end
26
+
27
+ def run(&block)
28
+ Process.fork do
29
+ loop do
30
+ self.scan
31
+ yield if block_given?
32
+ sleep 0.1
33
+ end
34
+ end
35
+ end
36
+ end
37
+ end
metadata ADDED
@@ -0,0 +1,48 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: simple_stats_store
3
+ version: !ruby/object:Gem::Version
4
+ version: 1.0.0
5
+ platform: ruby
6
+ authors:
7
+ - Joe Haig
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2015-05-15 00:00:00.000000000 Z
12
+ dependencies: []
13
+ description: Using SQLite3 to store statistics from a multithreaded application
14
+ email: joe.haig@bbc.co.uk
15
+ executables: []
16
+ extensions: []
17
+ extra_rdoc_files: []
18
+ files:
19
+ - README.md
20
+ - lib/simple_stats_store.rb
21
+ - lib/simple_stats_store/file_dump.rb
22
+ - lib/simple_stats_store/nil_dump.rb
23
+ - lib/simple_stats_store/server.rb
24
+ homepage: https://github.com/bbc/simple_stats_store
25
+ licenses:
26
+ - MIT
27
+ metadata: {}
28
+ post_install_message:
29
+ rdoc_options: []
30
+ require_paths:
31
+ - lib
32
+ required_ruby_version: !ruby/object:Gem::Requirement
33
+ requirements:
34
+ - - ">="
35
+ - !ruby/object:Gem::Version
36
+ version: '0'
37
+ required_rubygems_version: !ruby/object:Gem::Requirement
38
+ requirements:
39
+ - - ">="
40
+ - !ruby/object:Gem::Version
41
+ version: '0'
42
+ requirements: []
43
+ rubyforge_project:
44
+ rubygems_version: 2.2.2
45
+ signing_key:
46
+ specification_version: 4
47
+ summary: Simple Stats Store
48
+ test_files: []