spockets 0.0.3

Sign up to get free protection for your applications and to get access to all the features.
data/LICENSE ADDED
@@ -0,0 +1,165 @@
1
+ GNU LESSER GENERAL PUBLIC LICENSE
2
+ Version 3, 29 June 2007
3
+
4
+ Copyright (C) 2007 Free Software Foundation, Inc. <http://fsf.org/>
5
+ Everyone is permitted to copy and distribute verbatim copies
6
+ of this license document, but changing it is not allowed.
7
+
8
+
9
+ This version of the GNU Lesser General Public License incorporates
10
+ the terms and conditions of version 3 of the GNU General Public
11
+ License, supplemented by the additional permissions listed below.
12
+
13
+ 0. Additional Definitions.
14
+
15
+ As used herein, "this License" refers to version 3 of the GNU Lesser
16
+ General Public License, and the "GNU GPL" refers to version 3 of the GNU
17
+ General Public License.
18
+
19
+ "The Library" refers to a covered work governed by this License,
20
+ other than an Application or a Combined Work as defined below.
21
+
22
+ An "Application" is any work that makes use of an interface provided
23
+ by the Library, but which is not otherwise based on the Library.
24
+ Defining a subclass of a class defined by the Library is deemed a mode
25
+ of using an interface provided by the Library.
26
+
27
+ A "Combined Work" is a work produced by combining or linking an
28
+ Application with the Library. The particular version of the Library
29
+ with which the Combined Work was made is also called the "Linked
30
+ Version".
31
+
32
+ The "Minimal Corresponding Source" for a Combined Work means the
33
+ Corresponding Source for the Combined Work, excluding any source code
34
+ for portions of the Combined Work that, considered in isolation, are
35
+ based on the Application, and not on the Linked Version.
36
+
37
+ The "Corresponding Application Code" for a Combined Work means the
38
+ object code and/or source code for the Application, including any data
39
+ and utility programs needed for reproducing the Combined Work from the
40
+ Application, but excluding the System Libraries of the Combined Work.
41
+
42
+ 1. Exception to Section 3 of the GNU GPL.
43
+
44
+ You may convey a covered work under sections 3 and 4 of this License
45
+ without being bound by section 3 of the GNU GPL.
46
+
47
+ 2. Conveying Modified Versions.
48
+
49
+ If you modify a copy of the Library, and, in your modifications, a
50
+ facility refers to a function or data to be supplied by an Application
51
+ that uses the facility (other than as an argument passed when the
52
+ facility is invoked), then you may convey a copy of the modified
53
+ version:
54
+
55
+ a) under this License, provided that you make a good faith effort to
56
+ ensure that, in the event an Application does not supply the
57
+ function or data, the facility still operates, and performs
58
+ whatever part of its purpose remains meaningful, or
59
+
60
+ b) under the GNU GPL, with none of the additional permissions of
61
+ this License applicable to that copy.
62
+
63
+ 3. Object Code Incorporating Material from Library Header Files.
64
+
65
+ The object code form of an Application may incorporate material from
66
+ a header file that is part of the Library. You may convey such object
67
+ code under terms of your choice, provided that, if the incorporated
68
+ material is not limited to numerical parameters, data structure
69
+ layouts and accessors, or small macros, inline functions and templates
70
+ (ten or fewer lines in length), you do both of the following:
71
+
72
+ a) Give prominent notice with each copy of the object code that the
73
+ Library is used in it and that the Library and its use are
74
+ covered by this License.
75
+
76
+ b) Accompany the object code with a copy of the GNU GPL and this license
77
+ document.
78
+
79
+ 4. Combined Works.
80
+
81
+ You may convey a Combined Work under terms of your choice that,
82
+ taken together, effectively do not restrict modification of the
83
+ portions of the Library contained in the Combined Work and reverse
84
+ engineering for debugging such modifications, if you also do each of
85
+ the following:
86
+
87
+ a) Give prominent notice with each copy of the Combined Work that
88
+ the Library is used in it and that the Library and its use are
89
+ covered by this License.
90
+
91
+ b) Accompany the Combined Work with a copy of the GNU GPL and this license
92
+ document.
93
+
94
+ c) For a Combined Work that displays copyright notices during
95
+ execution, include the copyright notice for the Library among
96
+ these notices, as well as a reference directing the user to the
97
+ copies of the GNU GPL and this license document.
98
+
99
+ d) Do one of the following:
100
+
101
+ 0) Convey the Minimal Corresponding Source under the terms of this
102
+ License, and the Corresponding Application Code in a form
103
+ suitable for, and under terms that permit, the user to
104
+ recombine or relink the Application with a modified version of
105
+ the Linked Version to produce a modified Combined Work, in the
106
+ manner specified by section 6 of the GNU GPL for conveying
107
+ Corresponding Source.
108
+
109
+ 1) Use a suitable shared library mechanism for linking with the
110
+ Library. A suitable mechanism is one that (a) uses at run time
111
+ a copy of the Library already present on the user's computer
112
+ system, and (b) will operate properly with a modified version
113
+ of the Library that is interface-compatible with the Linked
114
+ Version.
115
+
116
+ e) Provide Installation Information, but only if you would otherwise
117
+ be required to provide such information under section 6 of the
118
+ GNU GPL, and only to the extent that such information is
119
+ necessary to install and execute a modified version of the
120
+ Combined Work produced by recombining or relinking the
121
+ Application with a modified version of the Linked Version. (If
122
+ you use option 4d0, the Installation Information must accompany
123
+ the Minimal Corresponding Source and Corresponding Application
124
+ Code. If you use option 4d1, you must provide the Installation
125
+ Information in the manner specified by section 6 of the GNU GPL
126
+ for conveying Corresponding Source.)
127
+
128
+ 5. Combined Libraries.
129
+
130
+ You may place library facilities that are a work based on the
131
+ Library side by side in a single library together with other library
132
+ facilities that are not Applications and are not covered by this
133
+ License, and convey such a combined library under terms of your
134
+ choice, if you do both of the following:
135
+
136
+ a) Accompany the combined library with a copy of the same work based
137
+ on the Library, uncombined with any other library facilities,
138
+ conveyed under the terms of this License.
139
+
140
+ b) Give prominent notice with the combined library that part of it
141
+ is a work based on the Library, and explaining where to find the
142
+ accompanying uncombined form of the same work.
143
+
144
+ 6. Revised Versions of the GNU Lesser General Public License.
145
+
146
+ The Free Software Foundation may publish revised and/or new versions
147
+ of the GNU Lesser General Public License from time to time. Such new
148
+ versions will be similar in spirit to the present version, but may
149
+ differ in detail to address new problems or concerns.
150
+
151
+ Each version is given a distinguishing version number. If the
152
+ Library as you received it specifies that a certain numbered version
153
+ of the GNU Lesser General Public License "or any later version"
154
+ applies to it, you have the option of following the terms and
155
+ conditions either of that published version or of any later version
156
+ published by the Free Software Foundation. If the Library as you
157
+ received it does not specify a version number of the GNU Lesser
158
+ General Public License, you may choose any version of the GNU Lesser
159
+ General Public License ever published by the Free Software Foundation.
160
+
161
+ If the Library as you received it specifies that a proxy can decide
162
+ whether future versions of the GNU Lesser General Public License shall
163
+ apply, that proxy's public statement of acceptance of any version is
164
+ permanent authorization for you to choose that version for the
165
+ Library.
data/README ADDED
@@ -0,0 +1,73 @@
1
+ == Spockets ==
2
+
3
+ Spockets is a simple library for dealing with multiple sockets.
4
+ You supply a socket, and one or more blocks to
5
+ execute, and Spockets will make sure those blocks get
6
+ executed when something comes in over the wire. It's just
7
+ that simple.
8
+
9
+ There is one requirement for spockets and that is the ActionPool.
10
+ This just allows spockets to use a thread pool for executing
11
+ blocks so you don't end up having to wait on slow blocks. You
12
+ can even provide your own pool for spockets to use, so all the
13
+ action can stay in one local pool.
14
+
15
+ install (easy):
16
+
17
+ gem install spockets
18
+
19
+ install (less easy):
20
+
21
+ git clone http://github.com/spox/spockets.git
22
+ cd spockets
23
+ gem build spockets.gemspec
24
+ gem install spockets-x.x.x.gem
25
+
26
+ It has RDocs. They are where ever your rubygems installed them.
27
+ They will probably be helpful to look over.
28
+
29
+ Examples are usually helpful, so here we go:
30
+
31
+ Code:
32
+
33
+ require 'socket'
34
+ require 'spockets'
35
+ spockets = Spockets::Spockets.new
36
+
37
+ se = TCPServer.new(3000)
38
+ loop do
39
+ s = se.accept
40
+ puts "Socket: #{s}"
41
+ spockets.add(s){|string| puts "#{s}: #{string}" }
42
+ end
43
+ sleep
44
+
45
+
46
+ Connecting:
47
+
48
+ > telnet 192.168.0.95 3000
49
+ Trying 192.168.0.95...
50
+ Connected to 192.168.0.95.
51
+ Escape character is '^]'.
52
+ goodbyeworld
53
+ ^]
54
+ telnet> quit
55
+ Connection closed.
56
+
57
+ > telnet 192.168.0.95 3000
58
+ Trying 192.168.0.95...
59
+ Connected to 192.168.0.95.
60
+ Escape character is '^]'.
61
+ foobar
62
+ complete
63
+ ^]
64
+ telnet> quit
65
+ Connection closed.
66
+
67
+ Output:
68
+
69
+ Socket: #<TCPSocket:0x98ec5ac>
70
+ Socket: #<TCPSocket:0x98ec37c>
71
+ #<TCPSocket:0x98ec37c>: foobar
72
+ #<TCPSocket:0x98ec5ac>: goodbyeworld
73
+ #<TCPSocket:0x98ec37c>: complete
data/README~ ADDED
@@ -0,0 +1,27 @@
1
+ == Spockets ==
2
+
3
+ Spockets is a simple library for dealing with multiple sockets.
4
+ You supply a socket, and one or more blocks to
5
+ execute, and Spockets will make sure those blocks get
6
+ executed when something comes in over the wire. It's just
7
+ that simple.
8
+
9
+ There is one requirement for spockets and that is the ActionPool.
10
+ This just allows spockets to use a thread pool for executing
11
+ blocks so you don't end up having to wait on slow blocks. You
12
+ can even provide your own pool for spockets to use, so all the
13
+ action can stay in one local pool.
14
+
15
+ install (easy):
16
+
17
+ gem install --source gems.github.com spockets
18
+
19
+ install (less easy):
20
+
21
+ git clone http://github.com/spox/spockets.git
22
+ cd spockets
23
+ gem build spockets.gemspec
24
+ gem install spockets-x.x.x.gem
25
+
26
+ It has RDocs. They are where ever your rubygems installed them.
27
+ They will probably be helpful to look over.
@@ -0,0 +1,37 @@
1
+ module Spockets
2
+
3
+ class DuplicateSocket < Exception
4
+ attr_reader :socket
5
+ def initialize(s)
6
+ @socket = s
7
+ end
8
+ end
9
+
10
+ class UnknownSocket < Exception
11
+ attr_reader :socket
12
+ def initialize(s)
13
+ @socket = s
14
+ end
15
+ end
16
+
17
+ class AlreadyRunning < Exception
18
+ end
19
+
20
+ class NotRunning < Exception
21
+ end
22
+
23
+ class Resync < Exception
24
+ end
25
+
26
+ class MissingArgument < Exception
27
+ attr_reader :argument
28
+ def initialize(a)
29
+ @argument = a
30
+ end
31
+
32
+ def to_s
33
+ "Missing required argument: #{@argument}"
34
+ end
35
+ end
36
+
37
+ end
@@ -0,0 +1,86 @@
1
+ require 'spockets/Exceptions'
2
+ require 'spockets/Watcher'
3
+
4
+ module Spockets
5
+
6
+ class Spockets
7
+
8
+ alias :delete, :remove
9
+
10
+ # :pool:: ActionPool if you would like to consolidate
11
+ # :clean:: Clean string. Set to true for default or
12
+ # provide a block to clean strings
13
+ # creates a new holder
14
+ def initialize(args={})
15
+ @sockets = {}
16
+ @watcher = Watcher.new(:sockets => @sockets, :clean => args[:clean], :pool => args[:pool])
17
+ end
18
+
19
+ # socket:: socket to listen to
20
+ # block:: block to execute when activity is received
21
+ # Adds a socket to the list to listen to. When a string
22
+ # is received on the socket, it will send it to the block
23
+ # for processing
24
+ def add(socket, &block)
25
+ raise DuplicateSocket.new(socket) if @sockets.has_key?(socket)
26
+ @sockets[socket] = [block]
27
+ begin
28
+ @watcher.sync
29
+ rescue NotRunning
30
+ start
31
+ end
32
+ end
33
+
34
+ # socket:: socket in list
35
+ # block:: additional block to execute
36
+ # This will add additional blocks to the associated
37
+ # socket to be executed when a new string is received
38
+ def extra(socket, &block)
39
+ raise UnknownSocket.new(socket) unless @sockets.has_key?(socket)
40
+ @sockets[socket] << block
41
+ end
42
+
43
+ # socket:: socket to remove
44
+ # Removes socket from list
45
+ def remove(socket)
46
+ raise UnknownSocket.new(socket) unless @sockets.has_key?(socket)
47
+ @sockets.delete(socket)
48
+ begin
49
+ @watcher.sync
50
+ rescue NotRunning
51
+ start
52
+ end
53
+ end
54
+
55
+ # remove all sockets
56
+ def clear
57
+ @sockets.clear
58
+ stop
59
+ end
60
+
61
+ # start spockets
62
+ def start
63
+ raise AlreadyRunning.new if @watcher.running?
64
+ @watcher.start
65
+ end
66
+
67
+ # stop spockets
68
+ def stop
69
+ raise NotRunning.new unless @watcher.running?
70
+ @watcher.stop
71
+ end
72
+
73
+ # currently watching sockets
74
+ def running?
75
+ !@watcher.nil? && @watcher.running?
76
+ end
77
+
78
+ # socket:: a socket
79
+ # check if the given socket is being watched
80
+ def include?(socket)
81
+ @sockets.has_key?(socket)
82
+ end
83
+
84
+ end
85
+
86
+ end
@@ -0,0 +1,85 @@
1
+ require 'spockets/Exceptions'
2
+ require 'spockets/Watcher'
3
+
4
+ module Spockets
5
+
6
+ class Spockets
7
+
8
+ alias :delete, :remove
9
+
10
+ # :pool:: ActionPool if you would like to consolidate
11
+ # :clean:: Clean string. Set to true for default or
12
+ # provide a block to clean strings
13
+ # creates a new holder
14
+ def initialize(args={})
15
+ @sockets = {}
16
+ @watcher = Watcher.new(:sockets => @sockets, :clean => args[:clean], :pool => args[:pool])
17
+ end
18
+
19
+ # socket:: socket to listen to
20
+ # block:: block to execute when activity is received
21
+ # Adds a socket to the list to listen to. When a string
22
+ # is received on the socket, it will send it to the block
23
+ # for processing
24
+ def add(socket, &block)
25
+ raise DuplicateSocket.new(socket) if @sockets.has_key?(socket)
26
+ @sockets[socket] = [block]
27
+ begin
28
+ @watcher.sync
29
+ rescue NotRunning
30
+ start
31
+ end
32
+ end
33
+
34
+ # socket:: socket in list
35
+ # block:: additional block to execute
36
+ # This will add additional blocks to the associated
37
+ # socket to be executed when a new string is received
38
+ def extra(socket, &block)
39
+ raise UnknownSocket.new(socket) unless @sockets.has_key?(socket)
40
+ @sockets[socket] << block
41
+ end
42
+
43
+ # socket:: socket to remove
44
+ # Removes socket from list
45
+ def remove(socket)
46
+ raise UnknownSocket.new(socket) unless @sockets.has_key?(socket)
47
+ @sockets.delete(socket)
48
+ begin
49
+ @watcher.sync
50
+ rescue NotRunning
51
+ start
52
+ end
53
+ end
54
+
55
+ def clear
56
+ @sockets.clear
57
+ stop
58
+ end
59
+
60
+ # start spockets
61
+ def start
62
+ raise AlreadyRunning.new if @watcher.running?
63
+ @watcher.start
64
+ end
65
+
66
+ # stop spockets
67
+ def stop
68
+ raise NotRunning.new unless @watcher.running?
69
+ @watcher.stop
70
+ end
71
+
72
+ # currently watching sockets
73
+ def running?
74
+ !@watcher.nil? && @watcher.running?
75
+ end
76
+
77
+ # socket:: a socket
78
+ # check if the given socket is being watched
79
+ def include?(socket)
80
+ @sockets.has_key?(socket)
81
+ end
82
+
83
+ end
84
+
85
+ end
@@ -0,0 +1,89 @@
1
+ require 'actionpool'
2
+ require 'actionpool/Exceptions'
3
+ require 'iconv'
4
+
5
+ module Spockets
6
+ class Watcher
7
+
8
+ # :sockets:: socket list
9
+ # :clean:: clean UTF8 strings or provide block to run on every read string
10
+ # :pool:: ActionPool to use
11
+ # Creates a new watcher for sockets
12
+ def initialize(args)
13
+ raise MissingArgument.new(:sockets) unless args[:sockets]
14
+ @sockets = args[:sockets]
15
+ @runner = nil
16
+ @clean = args[:clean] && (args[:clean].is_a?(Proc) || args[:clean].is_a?(TrueClass)) ? args[:clean] : nil
17
+ @pool = args[:pool] && args[:pool].is_a?(ActionPool::Pool) ? args[:pool] : ActionPool::Pool.new
18
+ @ic = @clean && @clean.is_a?(TrueClass) ? Iconv.new('UTF-8//IGNORE', 'UTF-8') : nil
19
+ @stop = true
20
+ end
21
+
22
+ # start the watcher
23
+ def start
24
+ @stop = false
25
+ @runner = Thread.new{watch} if @runner.nil? && @sockets.size > 0
26
+ end
27
+
28
+ # stop the watcher
29
+ def stop
30
+ @stop = true
31
+ @runner.join(0.1)
32
+ @runner.raise Resync.new
33
+ @runner.join(0.1)
34
+ @runner.kill unless @runner.alive?
35
+ @runner = nil
36
+ end
37
+
38
+ # is the watcher running?
39
+ def running?
40
+ !@stop
41
+ end
42
+
43
+ # clean incoming strings
44
+ def clean?
45
+ @clean
46
+ end
47
+
48
+ # Ensure all sockets are being listened to
49
+ def sync
50
+ raise NotRunning.new if @runner.nil?
51
+ @runner.raise Resync.new
52
+ end
53
+
54
+ private
55
+
56
+ def watch
57
+ until(@stop)
58
+ begin
59
+ puts 'we are watching'
60
+ resultset = Kernel.select(@sockets.keys, nil, nil, nil)
61
+ for sock in resultset[0]
62
+ string = sock.gets
63
+ if(sock.closed? || string.nil?)
64
+ @sockets.delete(sock)
65
+ else
66
+ string = clean? ? do_clean(string) : string
67
+ @sockets[sock].each{|b| @pool.process{ b.call(string)}}
68
+ end
69
+ end
70
+ rescue Resync
71
+ # break select and relisten #
72
+ end
73
+ end
74
+ @runner = nil
75
+ end
76
+
77
+ def do_clean(string)
78
+ unless(@ic.nil?)
79
+ return untaint(string)
80
+ else
81
+ return @clean.call(string)
82
+ end
83
+ end
84
+
85
+ def untaint(s)
86
+ @ic.iconv(s + ' ')[0..-2]
87
+ end
88
+ end
89
+ end
data/lib/spockets.rb ADDED
@@ -0,0 +1 @@
1
+ require 'spockets/Spockets'
Binary file
data/spockets.gemspec ADDED
@@ -0,0 +1,16 @@
1
+ spec = Gem::Specification.new do |s|
2
+ s.name = 'spockets'
3
+ s.author = %q(spox)
4
+ s.email = %q(spox@modspox.com)
5
+ s.version = '0.0.3'
6
+ s.summary = %q(Socket Helper)
7
+ s.platform = Gem::Platform::RUBY
8
+ s.has_rdoc = true
9
+ s.rdoc_options = %w(--title Spockets --main README --line-numbers)
10
+ s.extra_rdoc_files = %w(README)
11
+ s.files = Dir['**/*']
12
+ s.require_paths = %w(lib)
13
+ s.add_dependency 'ActionPool'
14
+ s.homepage = %q(http://dev.modspox.com/trac/spockets)
15
+ description = []
16
+ end
data/spockets.gemspec~ ADDED
@@ -0,0 +1,16 @@
1
+ spec = Gem::Specification.new do |s|
2
+ s.name = 'spockets'
3
+ s.author = %q(spox)
4
+ s.email = %q(spox@modspox.com)
5
+ s.version = '0.0.2'
6
+ s.summary = %q(Socket Helper)
7
+ s.platform = Gem::Platform::RUBY
8
+ s.has_rdoc = true
9
+ s.rdoc_options = %w(--title Spockets --main README --line-numbers)
10
+ s.extra_rdoc_files = %w(README)
11
+ s.files = Dir['**/*']
12
+ s.require_paths = %w(lib)
13
+ s.add_dependency 'ActionPool'
14
+ s.homepage = %q(http://dev.modspox.com/trac/spockets)
15
+ description = []
16
+ end
metadata ADDED
@@ -0,0 +1,78 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: spockets
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.3
5
+ platform: ruby
6
+ authors:
7
+ - spox
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+
12
+ date: 2009-04-24 00:00:00 -07:00
13
+ default_executable:
14
+ dependencies:
15
+ - !ruby/object:Gem::Dependency
16
+ name: ActionPool
17
+ type: :runtime
18
+ version_requirement:
19
+ version_requirements: !ruby/object:Gem::Requirement
20
+ requirements:
21
+ - - ">="
22
+ - !ruby/object:Gem::Version
23
+ version: "0"
24
+ version:
25
+ description:
26
+ email: spox@modspox.com
27
+ executables: []
28
+
29
+ extensions: []
30
+
31
+ extra_rdoc_files:
32
+ - README
33
+ files:
34
+ - README
35
+ - README~
36
+ - spockets.gemspec~
37
+ - spockets.gemspec
38
+ - lib
39
+ - lib/spockets
40
+ - lib/spockets/Spockets.rb~
41
+ - lib/spockets/Exceptions.rb
42
+ - lib/spockets/Watcher.rb
43
+ - lib/spockets/Spockets.rb
44
+ - lib/spockets.rb
45
+ - LICENSE
46
+ - spockets-0.0.2.gem
47
+ has_rdoc: true
48
+ homepage: http://dev.modspox.com/trac/spockets
49
+ post_install_message:
50
+ rdoc_options:
51
+ - --title
52
+ - Spockets
53
+ - --main
54
+ - README
55
+ - --line-numbers
56
+ require_paths:
57
+ - lib
58
+ required_ruby_version: !ruby/object:Gem::Requirement
59
+ requirements:
60
+ - - ">="
61
+ - !ruby/object:Gem::Version
62
+ version: "0"
63
+ version:
64
+ required_rubygems_version: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - ">="
67
+ - !ruby/object:Gem::Version
68
+ version: "0"
69
+ version:
70
+ requirements: []
71
+
72
+ rubyforge_project:
73
+ rubygems_version: 1.3.1
74
+ signing_key:
75
+ specification_version: 2
76
+ summary: Socket Helper
77
+ test_files: []
78
+