eventmachine-win32 0.5.3 → 0.7.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.
data/RELEASE_NOTES CHANGED
@@ -1,7 +1,20 @@
1
- $Id: RELEASE_NOTES 64 2006-05-17 07:00:16Z blackhedd $
1
+ $Id: RELEASE_NOTES 223 2006-08-08 20:30:41Z blackhedd $
2
2
 
3
3
  RUBY/EventMachine RELEASE NOTES
4
4
 
5
+ --------------------------------------------------
6
+ Version: 0.7.0, released xxAug06
7
+ Added a fix in em.cpp/ConnectToServer to fix a fatal exception that
8
+ occurred in FreeBSD when connecting successfully to a remote server.
9
+
10
+ --------------------------------------------------
11
+ Version: 0.6.0, released xxJul06
12
+ Added deferred operations, suggested by Don Stocks, amillionhitpoints@yahoo.com.
13
+
14
+ --------------------------------------------------
15
+ Version: 0.5.4, released xxJun06
16
+ Added get_peername support for streams and datagrams.
17
+
5
18
  --------------------------------------------------
6
19
  Version: 0.5.3, released 17May06
7
20
  Fixed bugs in extconf.rb, thanks to Daniel Harple, dharple@generalconsumption.org.
data/TODO ADDED
@@ -0,0 +1,10 @@
1
+ $Id: TODO 231 2006-08-13 17:15:53Z blackhedd $
2
+
3
+ TODO List:
4
+
5
+ 12Aug06: Noticed by Don Stocks. A TCP connect-request that results
6
+ in a failed DNS resolution fires a fatal error back to user code.
7
+ Uuuuuugly. We should probably cause an unbind event to get fired
8
+ instead, and add some parameterization so the caller can detect
9
+ the nature of the failure.
10
+
@@ -0,0 +1,89 @@
1
+ # $Id: deferrable.rb 216 2006-07-17 10:20:42Z blackhedd $
2
+ #
3
+ # Author:: blackhedd (gmail address: garbagecat10).
4
+ # Date:: 16 July 2006
5
+ #
6
+ # Copyright (C) 2006 by Francis Cianfrocca. All Rights Reserved.
7
+ #
8
+ # This program is made available under the terms of the GPL version 2.
9
+ #
10
+ # See EventMachine and EventMachine::Connection for documentation and
11
+ # usage examples.
12
+ #
13
+ #----------------------------------------------------------------------------
14
+ #
15
+ # Copyright (C) 2006 by Francis Cianfrocca. All Rights Reserved.
16
+ #
17
+ # Gmail: garbagecat10
18
+ #
19
+ # This program is free software; you can redistribute it and/or modify
20
+ # it under the terms of the GNU General Public License as published by
21
+ # the Free Software Foundation; either version 2 of the License, or
22
+ # (at your option) any later version.
23
+ #
24
+ # This program is distributed in the hope that it will be useful,
25
+ # but WITHOUT ANY WARRANTY; without even the implied warranty of
26
+ # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
27
+ # GNU General Public License for more details.
28
+ #
29
+ # You should have received a copy of the GNU General Public License
30
+ # along with this program; if not, write to the Free Software
31
+ # Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
32
+ #
33
+ #---------------------------------------------------------------------------
34
+ #
35
+ #
36
+
37
+ require 'forwardable'
38
+
39
+ module EventMachine
40
+
41
+ module Deferrable
42
+ def callback &block
43
+ return unless block
44
+ if @deferred_status == :succeeded
45
+ block.call
46
+ else
47
+ @callbacks ||= []
48
+ @callbacks << block
49
+ end
50
+ end
51
+
52
+ def errback &block
53
+ return unless block
54
+ if @deferred_status == :failed
55
+ block.call
56
+ else
57
+ @errbacks ||= []
58
+ @errbacks << block
59
+ end
60
+ end
61
+
62
+ # Note that if you call this method without arguments,
63
+ # no arguments will be passed to the callback/errback.
64
+ # If the user has coded these with arguments, then the
65
+ # user code will throw an argument exception.
66
+ # Implementors of deferrable classes <b>must</b>
67
+ # document the arguments they will supply to user callbacks.
68
+ def set_deferred_status arg, *args
69
+ @deferred_status = arg
70
+ @deferred_args = args
71
+ case @deferred_status
72
+ when :succeeded
73
+ if @callbacks
74
+ while cb = @callbacks.shift
75
+ cb.call *@deferred_args
76
+ end
77
+ end
78
+ when :failed
79
+ if @errbacks
80
+ while eb = @errbacks.shift
81
+ eb.call *@deferred_args
82
+ end
83
+ end
84
+ end
85
+ end
86
+
87
+ end
88
+ end
89
+
@@ -0,0 +1,50 @@
1
+ # $Id: eventable.rb 252 2006-09-02 19:23:20Z blackhedd $
2
+ #
3
+ # Author:: blackhedd (gmail address: garbagecat10).
4
+ # Date:: 16 July 2006
5
+ #
6
+ # Copyright (C) 2006 by Francis Cianfrocca. All Rights Reserved.
7
+ #
8
+ # This program is made available under the terms of the GPL version 2.
9
+ #
10
+ # See EventMachine and EventMachine::Connection for documentation and
11
+ # usage examples.
12
+ #
13
+ #----------------------------------------------------------------------------
14
+ #
15
+ # Copyright (C) 2006 by Francis Cianfrocca. All Rights Reserved.
16
+ #
17
+ # Gmail: garbagecat10
18
+ #
19
+ # This program is free software; you can redistribute it and/or modify
20
+ # it under the terms of the GNU General Public License as published by
21
+ # the Free Software Foundation; either version 2 of the License, or
22
+ # (at your option) any later version.
23
+ #
24
+ # This program is distributed in the hope that it will be useful,
25
+ # but WITHOUT ANY WARRANTY; without even the implied warranty of
26
+ # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
27
+ # GNU General Public License for more details.
28
+ #
29
+ # You should have received a copy of the GNU General Public License
30
+ # along with this program; if not, write to the Free Software
31
+ # Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
32
+ #
33
+ #---------------------------------------------------------------------------
34
+ #
35
+ #
36
+
37
+
38
+ module EventMachine
39
+ module Eventable
40
+
41
+ def listen_event event_name
42
+ end
43
+
44
+ def post_event event_name, arg
45
+ end
46
+
47
+ end
48
+ end
49
+
50
+
data/lib/eventmachine.rb CHANGED
@@ -1,6 +1,6 @@
1
- # $Id: eventmachine.rb 52 2006-05-16 01:01:46Z blackhedd $
1
+ # $Id: eventmachine.rb 283 2006-11-22 14:44:38Z blackhedd $
2
2
  #
3
- # Author:: blackhedd (gmail address: garbagecat20).
3
+ # Author:: blackhedd (gmail address: garbagecat10).
4
4
  # Date:: 8 Apr 2006
5
5
  #
6
6
  # Copyright (C) 2006 by Francis Cianfrocca. All Rights Reserved.
@@ -34,7 +34,31 @@
34
34
  #
35
35
  #
36
36
 
37
- require 'rubyeventmachine'
37
+
38
+ #-- Select in a library based on a global variable.
39
+ case $eventmachine_library
40
+ when :pure_ruby
41
+ require 'pr_eventmachine'
42
+ when :extension
43
+ require 'rubyeventmachine'
44
+ else
45
+ # This is the case that most user code will take.
46
+ # Prefer the extension if available.
47
+ begin
48
+ require 'rubyeventmachine'
49
+ rescue LoadError
50
+ require 'pr_eventmachine'
51
+ end
52
+ end
53
+
54
+
55
+ require "eventmachine_version"
56
+ require 'em/deferrable'
57
+ require 'em/eventable'
58
+ #-- Additional requires are at the BOTTOM of this file, because they
59
+ #-- depend on stuff defined in here. Refactor that someday.
60
+
61
+
38
62
 
39
63
  # == Introduction
40
64
  # EventMachine provides a fast, lightweight framework for implementing
@@ -132,7 +156,6 @@ require 'rubyeventmachine'
132
156
  #
133
157
  module EventMachine
134
158
 
135
- VERSION = "0.5.3"
136
159
 
137
160
  # EventMachine::run initializes and runs an event loop.
138
161
  # This method only returns if user-callback code calls stop_event_loop.
@@ -187,7 +210,7 @@ module EventMachine
187
210
  # Ruby threads.
188
211
  def EventMachine::run_without_threads &block
189
212
  #EventMachine::run false, &block
190
- EventMachine::run &block
213
+ EventMachine::run(&block)
191
214
  end
192
215
 
193
216
  # EventMachine#add_timer adds a one-shot timer to the event loop.
@@ -226,12 +249,15 @@ module EventMachine
226
249
  # }
227
250
  #
228
251
  #
252
+ #--
253
+ # Changed 04Oct06: We now pass the interval as an integer number of milliseconds.
254
+ #
229
255
  def EventMachine::add_timer *args, &block
230
256
  interval = args.shift
231
257
  code = args.shift || block
232
258
  if code
233
259
  # check too many timers!
234
- s = add_oneshot_timer interval
260
+ s = add_oneshot_timer((interval * 1000).to_i)
235
261
  @timers[s] = code
236
262
  end
237
263
  end
@@ -409,7 +435,7 @@ module EventMachine
409
435
  # }
410
436
  #
411
437
  #
412
- def EventMachine::start_server server, port, handler=nil
438
+ def EventMachine::start_server server, port, handler=nil, &block
413
439
  klass = if (handler and handler.is_a?(Class))
414
440
  handler
415
441
  else
@@ -417,7 +443,19 @@ module EventMachine
417
443
  end
418
444
 
419
445
  s = start_tcp_server server, port
420
- @acceptors[s] = klass
446
+ @acceptors[s] = [klass,block]
447
+ end
448
+
449
+
450
+ def EventMachine::start_unix_domain_server filename, handler=nil, &block
451
+ klass = if (handler and handler.is_a?(Class))
452
+ handler
453
+ else
454
+ Class.new( Connection ) {handler and include handler}
455
+ end
456
+
457
+ s = start_unix_server filename
458
+ @acceptors[s] = [klass,block]
421
459
  end
422
460
 
423
461
  # EventMachine#connect initiates a TCP connection to a remote
@@ -533,6 +571,29 @@ module EventMachine
533
571
  end
534
572
 
535
573
 
574
+ #--
575
+ # EXPERIMENTAL. DO NOT RELY ON THIS METHOD TO BE HERE IN THIS FORM, OR AT ALL.
576
+ # (03Nov06)
577
+ # Observe, the test for already-connected FAILS if we call a reconnect inside post_init,
578
+ # because we haven't set up the connection in @conns by that point.
579
+ # RESIST THE TEMPTATION to "fix" this problem by redefining the behavior of post_init.
580
+ #
581
+ # Changed 22Nov06: if called on an already-connected handler, just return the
582
+ # handler and do nothing more. Originally this condition raised an exception.
583
+ # We may want to change it yet again and call the block, if any.
584
+ #
585
+ def EventMachine::reconnect server, port, handler
586
+ raise "invalid handler" unless handler.respond_to?(:connection_completed)
587
+ #raise "still connected" if @conns.has_key?(handler.signature)
588
+ return handler if @conns.has_key?(handler.signature)
589
+ s = connect_server server, port
590
+ handler.signature = s
591
+ @conns[s] = handler
592
+ block_given? and yield handler
593
+ handler
594
+ end
595
+
596
+
536
597
  # EventMachine#open_datagram_socket is for support of UDP-based
537
598
  # protocols. Its usage is similar to that of EventMachine#start_server.
538
599
  # It takes three parameters: an IP address (which must be valid
@@ -586,6 +647,25 @@ module EventMachine
586
647
  # necessarily ones that have sent data to which you are responding),
587
648
  # then see Connection#send_datagram.
588
649
  #
650
+ #--
651
+ # Replaced the implementation on 01Oct06. Thanks to Tobias Gustafsson for pointing
652
+ # out that this originally did not take a class but only a module.
653
+ #
654
+ def self::open_datagram_socket address, port, handler=nil
655
+ klass = if (handler and handler.is_a?(Class))
656
+ handler
657
+ else
658
+ Class.new( Connection ) {handler and include handler}
659
+ end
660
+
661
+ s = open_udp_socket address, port
662
+ c = klass.new s
663
+ @conns[s] = c
664
+ block_given? and yield c
665
+ c
666
+ end
667
+ =begin
668
+ (Original, replaced 01Oct06)
589
669
  def self::open_datagram_socket address, port, handler=nil
590
670
  s = open_udp_socket address, port
591
671
  klass = Class.new( Connection ) {
@@ -596,6 +676,93 @@ module EventMachine
596
676
  block_given? and yield c
597
677
  c
598
678
  end
679
+ =end
680
+
681
+
682
+ # For advanced users. This function sets the default timer granularity, which by default is
683
+ # slightly smaller than 100 milliseconds. Call this function to set a higher or lower granularity.
684
+ # The function affects the behavior of #add_timer and #add_periodic_timer. Most applications
685
+ # will not need to call this function.
686
+ #
687
+ # The argument is a number of milliseconds. Avoid setting the quantum to very low values because
688
+ # that may reduce performance under some extreme conditions. We recommend that you not set a quantum
689
+ # lower than 10.
690
+ #
691
+ # You MUST call this function while an EventMachine loop is running (that is, after a call to
692
+ # EventMachine#run and before a subsequent call to EventMachine#stop).
693
+ #
694
+ def self::set_quantum mills
695
+ set_timer_quantum mills.to_i
696
+ end
697
+
698
+
699
+ def self::run_deferred_callbacks # :nodoc:
700
+ until @resultqueue.empty?
701
+ result,cback = @resultqueue.pop
702
+ cback.call result if cback
703
+ end
704
+ end
705
+
706
+ # #defer is for integrating blocking operations into EventMachine's control flow.
707
+ # Call #defer with one or two blocks, as shown below (the second block is <i>optional</i>):
708
+ #
709
+ # operation = proc {
710
+ # # perform a long-running operation here, such as a database query.
711
+ # "result" # as usual, the last expression evaluated in the block will be the return value.
712
+ # }
713
+ # callback = proc {|result|
714
+ # # do something with result here, such as send it back to a network client.
715
+ # }
716
+ #
717
+ # EventMachine.defer( operation, callback )
718
+ #
719
+ # The action of #defer is to take the block specified in the first parameter (the "operation")
720
+ # and schedule it for asynchronous execution on an internal thread pool maintained by EventMachine.
721
+ # When the operation completes, it will pass the result computed by the block (if any)
722
+ # back to the EventMachine reactor. Then, EventMachine calls the block specified in the
723
+ # second parameter to #defer (the "callback"), as part of its normal, synchronous
724
+ # event handling loop. The result computed by the operation block is passed as a parameter
725
+ # to the callback. You may omit the callback parameter if you don't need to execute any code
726
+ # after the operation completes.
727
+ #
728
+ # <i>Caveats:</i>
729
+ # This is a <b>provisional</b> implementation and is subject to change.
730
+ # Note carefully that the code in your deferred operation will be executed on a separate
731
+ # thread from the main EventMachine processing and all other Ruby threads that may exist in
732
+ # your program. Also, multiple deferred operations may be running at once! Therefore, you
733
+ # are responsible for ensuring that your operation code is threadsafe. [Need more explanation
734
+ # and examples.]
735
+ # Don't write a deferred operation that will block forever. If so, the current implementation will
736
+ # not detect the problem, and the thread will never be returned to the pool. EventMachine limits
737
+ # the number of threads in its pool, so if you do this enough times, your subsequent deferred
738
+ # operations won't get a chance to run. [We might put in a timer to detect this problem.]
739
+ #
740
+ def self::defer op, callback = nil
741
+ unless @threadqueue
742
+
743
+ #start_server "127.0.0.1", 29999, DeferredTrigger
744
+ #@deferred_trigger = connect "127.0.0.1", 29999
745
+
746
+ require 'thread'
747
+ @threadqueue = Queue.new
748
+ @resultqueue = Queue.new
749
+ 20.times {|ix|
750
+ Thread.new {
751
+ my_ix = ix
752
+ loop {
753
+ op,cback = @threadqueue.pop
754
+ result = op.call
755
+ @resultqueue << [result, cback]
756
+ EventMachine.signal_loopbreak
757
+ #@deferred_trigger.send_data "."
758
+ }
759
+ }
760
+ }
761
+ end
762
+
763
+ @threadqueue << [op,callback]
764
+ end
765
+
599
766
 
600
767
 
601
768
  private
@@ -613,16 +780,44 @@ module EventMachine
613
780
  raise ConnectionNotBound
614
781
  end
615
782
  when ConnectionAccepted
616
- accep = @acceptors[conn_binding] or raise NoHandlerForAcceptedConnection
783
+ accep,blk = @acceptors[conn_binding]
784
+ raise NoHandlerForAcceptedConnection unless accep
617
785
  c = accep.new data
618
786
  @conns[data] = c
787
+ blk and blk.call(c)
788
+ c # (needed?)
619
789
  when TimerFired
620
790
  t = @timers.delete( data ) or raise UnknownTimerFired
621
791
  t.call
792
+ when ConnectionCompleted
793
+ c = @conns[conn_binding] or raise ConnectionNotBound
794
+ c.connection_completed
795
+ when LoopbreakSignalled
796
+ run_deferred_callbacks
622
797
  end
623
798
  end
624
799
 
625
800
 
801
+ # Documentation stub
802
+ #--
803
+ # This is a provisional implementation of a stream-oriented file access object.
804
+ # We also experiment with wrapping up some better exception reporting.
805
+ class << self
806
+ def _open_file_for_writing filename, handler=nil
807
+ klass = if (handler and handler.is_a?(Class))
808
+ handler
809
+ else
810
+ Class.new( Connection ) {handler and include handler}
811
+ end
812
+
813
+ s = _write_file filename
814
+ c = klass.new s
815
+ @conns[s] = c
816
+ block_given? and yield c
817
+ c
818
+ end
819
+ end
820
+
626
821
 
627
822
  # EventMachine::Connection is a class that is instantiated
628
823
  # by EventMachine's processing loop whenever a new connection
@@ -650,6 +845,9 @@ module EventMachine
650
845
  #
651
846
  class Connection
652
847
 
848
+ # EXPERIMENTAL. Added the reconnect methods, which may go away.
849
+ attr_accessor :signature
850
+
653
851
  def initialize sig #:nodoc:
654
852
  @signature = sig
655
853
  post_init
@@ -770,7 +968,24 @@ class Connection
770
968
  EventMachine::send_data @signature, data, data.length
771
969
  end
772
970
 
971
+ # #connection_completed is called by the event loop when a remote TCP connection
972
+ # attempt completes successfully. You can expect to get this notification after calls
973
+ # to EventMachine#connect. Remember that EventMachine makes remote connections
974
+ # asynchronously, just as with any other kind of network event. #connection_completed
975
+ # is intended primarily to assist with network diagnostics. For normal protocol
976
+ # handling, use #post_init to perform initial work on a new connection (such as
977
+ # send an initial set of data).
978
+ # #post_init will always be called. #connection_completed will only be called in case
979
+ # of a successful completion. A connection-attempt which fails will receive a call
980
+ # to #unbind after the failure.
981
+ def connection_completed
982
+ end
773
983
 
984
+ # Call #start_tls at any point to initiate TLS encryption on connected streams.
985
+ # The method is smart enough to know whether it should perform a server-side
986
+ # or a client-side handshake. An appropriate place to call #start_tls is in
987
+ # your redefined #post_init method.
988
+ #
774
989
  def start_tls
775
990
  EventMachine::start_tls @signature
776
991
  end
@@ -800,8 +1015,58 @@ class Connection
800
1015
  end
801
1016
 
802
1017
 
1018
+ # #get_peername is used with stream-connections to obtain the identity
1019
+ # of the remotely-connected peer. If a peername is available, this method
1020
+ # returns a sockaddr structure. The method returns nil if no peername is available.
1021
+ # You can use Socket#unpack_sockaddr_in and its variants to obtain the
1022
+ # values contained in the peername structure returned from #get_peername.
1023
+ def get_peername
1024
+ EventMachine::get_peername @signature
1025
+ end
1026
+
1027
+ # comm_inactivity_timeout returns the current value (in seconds) of the inactivity-timeout
1028
+ # property of network-connection and datagram-socket objects. A nonzero value
1029
+ # indicates that the connection or socket will automatically be closed if no read or write
1030
+ # activity takes place for at least that number of seconds.
1031
+ # A zero value (the default) specifies that no automatic timeout will take place.
1032
+ def comm_inactivity_timeout
1033
+ EventMachine::get_comm_inactivity_timeout @signature
1034
+ end
1035
+
1036
+ # Alias for #set_comm_inactivity_timeout.
1037
+ def comm_inactivity_timeout= value
1038
+ self.send :set_comm_inactivity_timeout, value
1039
+ end
1040
+
1041
+ # comm_inactivity_timeout= allows you to set the inactivity-timeout property for
1042
+ # a network connection or datagram socket. Specify a non-negative numeric value in seconds.
1043
+ # If the value is greater than zero, the connection or socket will automatically be closed
1044
+ # if no read or write activity takes place for at least that number of seconds.
1045
+ # Specify a value of zero to indicate that no automatic timeout should take place.
1046
+ # Zero is the default value.
1047
+ def set_comm_inactivity_timeout value
1048
+ EventMachine::set_comm_inactivity_timeout @signature, value
1049
+ end
1050
+
1051
+ #--
1052
+ # EXPERIMENTAL. DO NOT RELY ON THIS METHOD TO REMAIN SUPPORTED.
1053
+ # (03Nov06)
1054
+ def reconnect server, port
1055
+ EventMachine::reconnect server, port, self
1056
+ end
1057
+
803
1058
  end
804
1059
 
805
1060
 
806
1061
  end # module EventMachine
807
1062
 
1063
+ # At the bottom of this module, we load up protocol handlers that depend on some
1064
+ # of the classes defined here. Eventually we should refactor this out so it's
1065
+ # laid out in a more logical way.
1066
+ #
1067
+
1068
+ require 'protocols/tcptest'
1069
+ require 'protocols/httpclient'
1070
+ require 'protocols/line_and_text'
1071
+ require 'protocols/header_and_content'
1072
+