simple_stats_store 1.0.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/README.md +89 -0
- data/lib/simple_stats_store.rb +5 -0
- data/lib/simple_stats_store/file_dump.rb +40 -0
- data/lib/simple_stats_store/nil_dump.rb +7 -0
- data/lib/simple_stats_store/server.rb +37 -0
- metadata +48 -0
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,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,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: []
|