dash-fu 1.0.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (7) hide show
  1. data/CHANGELOG +3 -0
  2. data/README.md +36 -0
  3. data/VERSION +1 -0
  4. data/dash-fu.gemspec +17 -0
  5. data/lib/dash-fu.rb +94 -0
  6. data/test/test.rb +62 -0
  7. metadata +63 -0
data/CHANGELOG ADDED
@@ -0,0 +1,3 @@
1
+ 1.0.0 on 2011-08-19
2
+
3
+ First release
data/README.md ADDED
@@ -0,0 +1,36 @@
1
+ Use me to push data to [Dash-fu](http://dash-fu.com) in real time.
2
+
3
+
4
+ The only configuration you need is setting the API key in
5
+ `config/environments/production.rb`:
6
+
7
+ DashFu.api_key = "<your API key>"
8
+
9
+ Your API key is available from [account settings](http://dash-fu.com/settings).
10
+
11
+ You only want to push data in production, so make sure the API key is only set
12
+ in production environment. Calls to created/active with no API key are
13
+ simply ignored.
14
+
15
+
16
+ You can send events by calling DashFu.push with UID and event, or using the
17
+ specialized created and active methods.
18
+
19
+ For example, to assign a user to a cohort, we're going to notify Dash-fu
20
+ whenever an acount gets created:
21
+
22
+ class User < ActiveRecord::Model
23
+ after_create do
24
+ DashFu.created id
25
+ end
26
+ end
27
+
28
+ In this example, we consider a user active whenever they post a status update,
29
+ and notify Dash-fu accordingly:
30
+
31
+ class StatusUpdate < ActiveRecord::Model
32
+ after_create do
33
+ DashFu.active id
34
+ end
35
+ end
36
+
data/VERSION ADDED
@@ -0,0 +1 @@
1
+ 1.0.0
data/dash-fu.gemspec ADDED
@@ -0,0 +1,17 @@
1
+ $: << File.dirname(__FILE__) + "/lib"
2
+
3
+ Gem::Specification.new do |spec|
4
+ spec.name = "dash-fu"
5
+ spec.version = IO.read("VERSION")
6
+ spec.author = "Assaf Arkin"
7
+ spec.email = "assaf@labnotes.org"
8
+ spec.homepage = "http://dash-fu.com"
9
+ spec.summary = "Use me to push data to Dash-fu in real time"
10
+ spec.description = ""
11
+ spec.post_install_message = IO.read("README.md")
12
+ spec.license = "Public domain"
13
+
14
+ spec.files = Dir["{bin,lib,test}/**/*", "CHANGELOG", "VERSION", "README.md", "*.gemspec"]
15
+
16
+ spec.required_ruby_version = '>= 1.8.7'
17
+ end
data/lib/dash-fu.rb ADDED
@@ -0,0 +1,94 @@
1
+ require "socket"
2
+
3
+
4
+ # Use me to push data to Dash-fu in real time.
5
+ #
6
+ #
7
+ # The only configuration you need is setting the API key in
8
+ # config/environments/production.rb:
9
+ #
10
+ # DashFu.api_key = "<your API key>"
11
+ #
12
+ # You only want to push data in production, so make sure the API key is only set
13
+ # in production environment. Calls to created/active with no API key are
14
+ # simply ignored.
15
+ #
16
+ #
17
+ # You can send events by calling DashFu.push with UID and event, or using the
18
+ # specialized created and active methods.
19
+ #
20
+ # For example, to assign a user to a cohort, we're going to notify Dash-fu
21
+ # whenever an acount gets created:
22
+ #
23
+ # class User < ActiveRecord::Model
24
+ # after_create do
25
+ # DashFu.created id
26
+ # end
27
+ # end
28
+ #
29
+ # In this example, we consider a user active whenever they post a status update,
30
+ # and notify Dash-fu accordingly:
31
+ #
32
+ # class StatusUpdate < ActiveRecord::Model
33
+ # after_create do
34
+ # DashFu.active id
35
+ # end
36
+ # end
37
+ module DashFu
38
+ @mutex = Mutex.new
39
+
40
+ class << self
41
+ # DashFu.host is set by default, this is only useful for testing.
42
+ attr_accessor :host, :port
43
+
44
+ # Set the API key with:
45
+ # DashFu.api_key = "<your API key>"
46
+ attr_accessor :api_key
47
+
48
+ # Records that a user has been active in the app.
49
+ def active(uid)
50
+ push uid, "active"
51
+ end
52
+
53
+ # Records that a new user account has been created (associate them with
54
+ # cohort).
55
+ def created(uid)
56
+ push uid, "created"
57
+ end
58
+
59
+ # Close connection. If you like crossing your t's you can call this when the
60
+ # app shutsdown.
61
+ def close
62
+ @mutex.synchronize do
63
+ socket, @socket = @socket, nil
64
+ socket.close if socket
65
+ end
66
+ rescue Exception
67
+ end
68
+
69
+ # Push update for the specified user ID and event. Or you can use
70
+ # active/created.
71
+ def push(uid, event)
72
+ return unless @api_key
73
+ if socket = @socket
74
+ socket.sendmsg_nonblock "POST /v1/push?api_key=#{@api_key}&uid=#{uid}&event=#{event} HTTP/1.1\r\nHost: #{@host}\r\nConnection: keep-alive\r\nContent-Length: 0\r\n\r\n", 0
75
+ socket.recv_nonblock 512 rescue nil
76
+ else
77
+ Thread.new do
78
+ @mutex.synchronize do
79
+ @socket ||= TCPSocket.open(@host, @port || 80)
80
+ end
81
+ push uid, event
82
+ end
83
+ end
84
+ rescue Errno::EPIPE, Errno::ECONNRESET, Errno::ETIMEDOUT
85
+ close
86
+ retry
87
+ rescue Errno::ECONNREFUSED, Errno::ENETUNREACH
88
+ # No @socket so we'll try to connect next time
89
+ end
90
+ end
91
+
92
+ # Default host name.
93
+ self.host = "beta.dash-fu.com"
94
+ end
data/test/test.rb ADDED
@@ -0,0 +1,62 @@
1
+ require "test/unit"
2
+ require "thread"
3
+ require "cgi"
4
+ require "webrick"
5
+ $: << File.dirname(__FILE__) + "/../lib"
6
+ $: << File.expand_path(File.dirname(__FILE__) + "/..")
7
+ require "dash-fu"
8
+
9
+
10
+ $ready = Queue.new
11
+ $server = WEBrick::HTTPServer.new(:Port=>3001, :StartCallback=>lambda { puts "go"; $ready << "go" }, :Logger=>WEBrick::Log.new(nil, WEBrick::Log::FATAL))
12
+ servlet = lambda do |request, response|
13
+ $request = request
14
+ response.status = 200
15
+ end
16
+ $server.mount "/v1/push", WEBrick::HTTPServlet::ProcHandler.new(servlet)
17
+ trap "INT" do
18
+ $server.shutdown
19
+ end
20
+ DashFu.host = "localhost"
21
+ DashFu.port = 3001
22
+
23
+
24
+ class Test::Unit::TestCase
25
+
26
+ end
27
+
28
+
29
+ # Test sending live data.
30
+ class LiveTest < Test::Unit::TestCase
31
+ def setup
32
+ DashFu.api_key = "foobar"
33
+ Thread.new { $server.start }
34
+ $ready.pop
35
+ $request = nil
36
+ end
37
+
38
+ def test_active_request
39
+ DashFu.active "56789"
40
+ sleep 0.2
41
+ assert_equal "/v1/push", $request.path
42
+ assert_equal "POST", $request.request_method
43
+ assert $request.keep_alive?
44
+ end
45
+
46
+ def test_active_data
47
+ DashFu.active "56789"
48
+ sleep 0.2
49
+ query = CGI.parse($request.query_string)
50
+ assert_equal ["foobar"], query["api_key"]
51
+ assert_equal ["active"], query["event"]
52
+ assert_equal ["56789"], query["uid"]
53
+ end
54
+
55
+ def teardown
56
+ $server.shutdown
57
+ end
58
+ end
59
+
60
+ # Test Dashfu API when no API key set (e.g. test and development environments).
61
+ class InactiveTest < Test::Unit::TestCase
62
+ end
metadata ADDED
@@ -0,0 +1,63 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: dash-fu
3
+ version: !ruby/object:Gem::Version
4
+ version: 1.0.0
5
+ prerelease:
6
+ platform: ruby
7
+ authors:
8
+ - Assaf Arkin
9
+ autorequire:
10
+ bindir: bin
11
+ cert_chain: []
12
+ date: 2011-08-22 00:00:00.000000000Z
13
+ dependencies: []
14
+ description: ''
15
+ email: assaf@labnotes.org
16
+ executables: []
17
+ extensions: []
18
+ extra_rdoc_files: []
19
+ files:
20
+ - lib/dash-fu.rb
21
+ - test/test.rb
22
+ - CHANGELOG
23
+ - VERSION
24
+ - README.md
25
+ - dash-fu.gemspec
26
+ homepage: http://dash-fu.com
27
+ licenses:
28
+ - Public domain
29
+ post_install_message: ! "Use me to push data to [Dash-fu](http://dash-fu.com) in real
30
+ time.\n\n\nThe only configuration you need is setting the API key in\n`config/environments/production.rb`:\n\n
31
+ \ DashFu.api_key = \"<your API key>\"\n\nYour API key is available from [account
32
+ settings](http://dash-fu.com/settings).\n\nYou only want to push data in production,
33
+ so make sure the API key is only set\nin production environment. Calls to created/active
34
+ with no API key are\nsimply ignored.\n\n\nYou can send events by calling DashFu.push
35
+ with UID and event, or using the\nspecialized created and active methods.\n\nFor
36
+ example, to assign a user to a cohort, we're going to notify Dash-fu\nwhenever an
37
+ acount gets created:\n\n class User < ActiveRecord::Model\n after_create
38
+ do\n DashFu.created id\n end\n end\n\nIn this example, we consider
39
+ a user active whenever they post a status update,\nand notify Dash-fu accordingly:\n\n
40
+ \ class StatusUpdate < ActiveRecord::Model\n after_create do\n DashFu.active
41
+ id\n end\n end\n\n"
42
+ rdoc_options: []
43
+ require_paths:
44
+ - lib
45
+ required_ruby_version: !ruby/object:Gem::Requirement
46
+ none: false
47
+ requirements:
48
+ - - ! '>='
49
+ - !ruby/object:Gem::Version
50
+ version: 1.8.7
51
+ required_rubygems_version: !ruby/object:Gem::Requirement
52
+ none: false
53
+ requirements:
54
+ - - ! '>='
55
+ - !ruby/object:Gem::Version
56
+ version: '0'
57
+ requirements: []
58
+ rubyforge_project:
59
+ rubygems_version: 1.8.8
60
+ signing_key:
61
+ specification_version: 3
62
+ summary: Use me to push data to Dash-fu in real time
63
+ test_files: []