celluloid-io-0.16.2/0000755000004100000410000000000012477620141014215 5ustar www-datawww-datacelluloid-io-0.16.2/Rakefile0000644000004100000410000000023512477620141015662 0ustar www-datawww-data#!/usr/bin/env rake require 'bundler/gem_tasks' Dir["tasks/**/*.task"].each { |task| load task } task :default => :spec task :ci => %w(spec benchmark) celluloid-io-0.16.2/Gemfile0000644000004100000410000000021012477620141015501 0ustar www-datawww-datasource 'https://rubygems.org' gemspec gem 'coveralls', require: false gem 'celluloid', github: 'celluloid/celluloid', branch: 'master' celluloid-io-0.16.2/examples/0000755000004100000410000000000012477620141016033 5ustar www-datawww-datacelluloid-io-0.16.2/examples/echo_client.rb0000644000004100000410000000074012477620141020635 0ustar www-datawww-data#!/usr/bin/env ruby require 'rubygems' require 'bundler/setup' require 'celluloid/io' class EchoClient include Celluloid::IO def initialize(host, port) puts "*** Connecting to echo server on #{host}:#{port}" # This is actually creating a Celluloid::IO::TCPSocket @socket = TCPSocket.new(host, port) end def echo(s) @socket.write(s) @socket.readpartial(4096) end end client = EchoClient.new("127.0.0.1", 1234) puts client.echo("TEST FOR ECHO") celluloid-io-0.16.2/examples/echo_unix_server.rb0000644000004100000410000000146312477620141021733 0ustar www-datawww-datarequire 'bundler/setup' require 'celluloid/io' class EchoUNIXServer include Celluloid::IO finalizer :finalize attr_reader :socket_path, :server def initialize(socket_path) puts "*** start server #{socket_path}" @socket_path = socket_path @server = UNIXServer.open(socket_path) async.run end def run loop { async.handle_connection @server.accept } end def handle_connection(socket) loop do data = socket.readline puts "*** gets data #{data}" socket.write(data) end rescue EOFError puts "*** disconnected" ensure socket.close end def finalize if @server @server.close File.delete(@socket_path) end end end supervisor = EchoUNIXServer.supervise("/tmp/sock_test") trap("INT") { supervisor.terminate; exit } sleep celluloid-io-0.16.2/examples/echo_server.rb0000755000004100000410000000162612477620141020674 0ustar www-datawww-data#!/usr/bin/env ruby # # Run this as: bundle exec examples/echo_server.rb require 'bundler/setup' require 'celluloid/io' class EchoServer include Celluloid::IO finalizer :finalize def initialize(host, port) puts "*** Starting echo server on #{host}:#{port}" # Since we included Celluloid::IO, we're actually making a # Celluloid::IO::TCPServer here @server = TCPServer.new(host, port) async.run end def finalize @server.close if @server end def run loop { async.handle_connection @server.accept } end def handle_connection(socket) _, port, host = socket.peeraddr puts "*** Received connection from #{host}:#{port}" loop { socket.write socket.readpartial(4096) } rescue EOFError puts "*** #{host}:#{port} disconnected" socket.close end end supervisor = EchoServer.supervise("127.0.0.1", 1234) trap("INT") { supervisor.terminate; exit } sleep celluloid-io-0.16.2/examples/echo_unix_client.rb0000644000004100000410000000104612477620141021700 0ustar www-datawww-datarequire 'bundler/setup' require 'celluloid/io' class EchoUNIXClient include Celluloid::IO finalizer :finalize def initialize(socket_path) puts "*** connecting to #{socket_path}" @socket_path = socket_path @socket = UNIXSocket.open(socket_path) end def echo(msg) puts "*** send to server: '#{msg}'" @socket.puts(msg) data = @socket.readline.chomp puts "*** server unswer '#{data}'" data end def finalize @socket.close if @socket end end c = EchoUNIXClient.new("/tmp/sock_test") c.echo("DATA") celluloid-io-0.16.2/.coveralls.yml0000644000004100000410000000003112477620141017002 0ustar www-datawww-dataservice-name: travis-pro celluloid-io-0.16.2/log/0000755000004100000410000000000012477620141014776 5ustar www-datawww-datacelluloid-io-0.16.2/log/.gitignore0000644000004100000410000000000612477620141016762 0ustar www-datawww-data*.log celluloid-io-0.16.2/.rspec0000644000004100000410000000010512477620141015326 0ustar www-datawww-data--color --format documentation --backtrace --order random --warnings celluloid-io-0.16.2/logo.png0000644000004100000410000006221712477620141015673 0ustar www-datawww-dataPNG  IHDR L pHYs   OiCCPPhotoshop ICC profilexڝSgTS=BKKoR RB&*! J!QEEȠQ, !{kּ> H3Q5 B.@ $pd!s#~<<+"x M0B\t8K@zB@F&S`cbP-`'{[! eDh;VEX0fK9-0IWfH  0Q){`##xFW<+*x<$9E[-qWW.(I+6aa@.y24x6_-"bbϫp@t~,/;m%h^ uf@Wp~<5j>{-]cK'Xto(hw?G%fIq^D$.Tʳ?D*A, `6B$BB dr`)B(Ͱ*`/@4Qhp.U=pa( Aa!ڈbX#!H$ ɈQ"K5H1RT UH=r9\F;2G1Q= C7F dt1r=6Ыhڏ>C03l0.B8, c˱" VcϱwE 6wB aAHXLXNH $4 7 Q'"K&b21XH,#/{C7$C2'ITFnR#,4H#dk9, +ȅ3![ b@qS(RjJ4e2AURݨT5ZBRQ4u9̓IKhhitݕNWGw Ljg(gwLӋT071oUX**| J&*/Tު UUT^S}FU3S ԖUPSSg;goT?~YYLOCQ_ cx,!k u5&|v*=9C3J3WRf?qtN (~))4L1e\kXHQG6EYAJ'\'GgSSݧ M=:.kDwn^Loy}/TmG X $ <5qo</QC]@Caaᄑ.ȽJtq]zۯ6iܟ4)Y3sCQ? 0k߬~OCOg#/c/Wװwa>>r><72Y_7ȷOo_C#dz%gA[z|!?:eAAA!h쐭!ΑiP~aa~ 'W?pX15wCsDDDޛg1O9-J5*>.j<74?.fYXXIlK9.*6nl {/]py.,:@LN8A*%w% yg"/6шC\*NH*Mz쑼5y$3,幄'L Lݛ:v m2=:1qB!Mggfvˬen/kY- BTZ(*geWf͉9+̳ې7ᒶKW-X潬j9(xoʿܔĹdff-[n ڴ VE/(ۻCɾUUMfeI?m]Nmq#׹=TR+Gw- 6 U#pDy  :v{vg/jBFS[b[O>zG499?rCd&ˮ/~јѡ򗓿m|x31^VwwO| (hSЧc3- cHRMz%u0`:o_FYIDATx{|U?ޤtPWtҩ+_uwЦ^]&zkeEdihjQwWEROumM.J'JTmM2?fRL$=뼀ҙ9sΜ33yGq@ !I@ "@@  @ @@ @ @ @ !@ D@өE"Qh 0H9<A BFyܦ9<'B @ eVkn0(@ '`ZWեV :ܹڹsŸ袋V?G@ @ZWӦM_b V jSoe˖xl}ǃ@ @ d_ oR,D"D"X,[$ )F9O<3go9<&@ 0DM6M---޷o߼'ˑT H8"  "۷oo~-B@ @䭷޺{?/ R χtwwO$A*.ɐ48"h…D Lfn+Ya[60EYifi%Pe'awЁB@0O`EGs\ z àVdhii Z<.̞=EaڴiAB544VTT+ J2T *%B aC 0^:/P9$IHxgڵ?4iىDz뭸;R zd\{+q-h4d2ɓ'AKHss3/zD1͔`(8 q803FcavvJAIOhFhL&|64\.x<$&&r^]]]Jc0k-clUUWW$??alHOHacEEE9Ο@UUU4]GZ@89E}-K!r>J5---]{?$^׈FŋmmmP(m۶mgd2}f͍1KO,$=K "JU8X,3!Ԉ:G#}BEZ,jȧ~zqWWWχlu]-&..5k|>:;;2wjkko$CL1Ο?C !HnnnNS&NSՍLY,dn# nb #dlٲlbb"d2-ZaE]%K )) Nsel%(G.jl&BD<\*u@ƒ£F" #gD oPq᪫BQQhDyp-z{{!Gό`1@ ~yx(a #gn!j"@.L&Coo/kŔ)SBr͌ \y啐H$=#7|#d2JV@XVY!^d2'-JCUP DRr7C*0c DKyC.d}Iut:78D|BaYsQ">(#\f(vD"/r9ɓqeSNŏcx<3O,ǧUVWrE 1`pA>@Acl:9 Gkky^deeC^'NDvv6|>yD4]g4 EP8I+#*- NහMDC}}d֭y<)qe|p'k0_}Ռ={ž^inn.;q]t'VŇb![!2dai"-JC 6̗oqʹեMMM35+.Ν;q7n~-3XVZZZ[VDQfYRi?AfJesL!6HcCCCPb(A0oe1ug0!$}SRUU. D"Q*_uHp8 (غu+u9">'8T*a4Mx2 c$H(̘L{ @ *TUUU&fUTH5!( `5BLl(1Y`s?zo߾!y`9_~%n7vGz QhѢ~%8h1X|X7UVVj9f64i4,t:˲MfggoM5//odggQT,iQB:%o] 8kBp]l޼y3ED"Ajj*ӑ'Q233\X?;w I]駟 J`Q*HKKCzz:7Yfvʔ)[GˠU!a{>ji4S8IјVk^}}}~QQ~L@Hz}9j0HKbX|Cpj/< Bl1k@B!BB ټy{뿨d8q"&L׋Vû R=zJs㢋.BL&áCt:q`Ĭ$ddd… yȳ>_@gg'0gᗿYL&Cvv6 oVZ6gq(++aYZ}L&u]ŋ[nArrddd ##eee{+WDSSۃYۏ;6@TWWFiNJm|OzvF)I!B+ * +BꫯWxx^tvv"..ZO<F|nXŋcʂ\.G{{;V^^z yN85k{7HaѢEXr%L2eggcٲeX|9RSSr ,(苿UP4hvn쳆2[A !A8߇pd5,!m̛ ?wZZv;O>ۚF#B&Np:xpw駟ƶmpix<p^`Xz5ϟ |8[||<-[Gy c޽?~7nT@kNNNnω3?˲eeeU *&GDFм!NIIAWW^/(BaaaБCgAkk+z{{؈FO…^!сCfȑ#Dx^p_xy"d`Y>Z[[SN U]]]z=|6V^W -GX-@,*O Bd8 ӭy*EU+@ۋ*)11'NL&ŋAӴ`Xd {^n;~ |ؼyc$ 8u.2hQm ;())]`  _|ŕcPt f Ed9q$!jp*c,~"D7h0|Bt ֮]/^/oo~D"A'QTT+===|HJJ:D"x^tuu8? 'avmA `ϦMèh4BD t@ aF'9D1t> `69t萼r9n7$ ZL<9$ם>}:ү{n7t:!Ӊ`IOOǝw XfH$/4tuu @:t蒱x 5k%1 @ <E=!/wY_r\.r̞=;d-*p5=| >r3k,̙3?Vn:'OZ4ֲ*M@ bI IB˶J 0e\p!mBoo~ok3 /G4iiz2@'K>_G0 s6"87]tQHs饗?<ψ Q"("_H_Yh0 '?ɾnaKNN` }|}D@ s/KJJTmV]MMMHék1yftB16?l֬YkwsT*Ess3됶7|vHa>5m[#~&(jpٻwŋHtcFFƮzoN+'c@ s.%%%fX#+\RR:5&YxEبC֐}_w_+oߎԩSزe mӧO_3<)ihh#$@ \[M\RR:+) He˖ .׮]`їOP ##'NH$n~D"T*=K\{뭷F1Q׫x~p#֒'8BZ/RDR4'y}@nzAiii={nsDBTntvv:H$ FJII;w x_}RRR.k*DD8C.ԩSxRP(?|>ddd@*B.V>A$1ؒCرڱc.X`pa2+B$֏a6)eiesV+Ų,}>#EYin(0 ²l63qkZ)6|M,EQV13 c%9l63}oXfiniB_TRRb1@B&2~N as ?|P#99L?W\ & .@||<`ٰo>|p\dJFVVn6Znƍ裏P(zwoĉ T*pA8Nvttt@*")) ,Y2$å{EJJ z{{?W?DBOPtr " .\q\… 7 |_T*2hC= d_WWw{_?xFl }A 0YRm 0ǖl7Lr8hhhPXQQaM*jF!c~m_Z\\&FSisZII ~Qă)b:DDMՆO)@JKK#++ 8~8 ##7t d'kooGSSn݊׃eY\.޽+VX,n5ł^z 'OEBB~[n-܂S"%%^~-N8>[l={xՅ+W8 "B㭷ނEoo/d2Z\veq 7 >>v6m~ݻŘ8q"GҢ +BL&VРV+F0:@]]̺5SVג#|tꊊQm?,//G8H}xFqj4̨9%%%XPM%k h #:䩧g94++ @BBf͚2̛7IIIgC"@Tbܹ;w.Y֭|rp[oj*\s ~򗿄R<㘴4M7݄oo6^~e8D"oKH}}=VX={v 7?)xL0 o8q֮]>ɓ'ɓ'رc&UV-?1 ?;;Q +=^UTUUUUUi0O>lt:]E?/v[RWWw{ TyyΏ6R iz^!B<(C̐gކfX_tB߲e<̓'̠jX~=!PL>Wƽދb߿<F}>vFz~wx뭷p)>4XG(//O<,r8NQ^H , a!ȫ: UBBzzzс8hZӟ8ćŏ~#,ZZZp)ᅬoӧOGff&Jtww={/@kkk0,Y+V@\\%$$`p\Xr%ZZZ5:?ayv̞=EEEG_ ?455III-3Tuuu`p@baɘip$" fJRU\\\˲lU,E@lo5MF԰Q^PX"@1bgl:p%}dyp뭷p|T,Z(W*"11J2IOOGBBR) qwcΜ9K"C~~>|>D"222aR)\.z{{!JT!)) . X|9M&hrssqqq8"m۶9B?4M719ʷDG,Bv,B$(tUUUma*>۫F>O.pٱcǤ\.0еBs 7`Μ9Ak@{{ . ݘ2e ͛z%''㮻D"AWW ˅x<' 8~MRaΜ9Aq$H-g|^7EeYZ6" C:*"!GUX"DV:ȓ9 (1H"LiW_}5$ۍ p !DJJJ02H$\.q|g  q p饗nsŌ3v=ϐB&@,/_f(233H3x566 $dB.Jl6TJUEzI>GL^cEMM#Xp2"H  79!33'OY%D".2$$$kWְK/roH$ahCABB.@Q zkQJeP(G& zY|0 !#l6S1etW  lQ< 8+D|_Xkjjh,kjjԡXGBHRb3(Q!%%%H$#}|' K. gp8qB)/gkvvJivmqpf2,HU.aUGgA30ƳEZjfs~BqJRYּH NuתP(}}0y_2͌jf2Tw[ ?aׁ@;ƹ0Ͱ탷W96Poo/Z[[G|\OOϰlt8_֢75M,UQz@m"DŽd̪mU(NFS醻 o0tlS5&VTT mRյɏ0L_f`09E!!`I`y!d555ĉ!ȁaxH$/T/HΝ;qmǎhkkX|fq'&ؠ999s CHsr4m7 卍999!/O %DZ n@| U'l.j|!l6SBMfh4 rmYiD$n8.@.^5qUr} gwlسgRyC!q1߿?d8p\CYbGP1 @ݬEEEo,[7 Mve r}e$‚F56C-Y-(//JWD"oM՚'l.B8א%Mp^a 'š 1CR={`A?Hx$%%Q!H H `6C&8Æ <`w*#ىmrOۋ3o>("\$pV֢7d0! ᤪL1e6B8 l6H%ZYY ŖNFcjll"@F̰"[&$$6l؀ݻw ~ k")) "Z󡧧8bHJJRfúuB p8~z\%r)))HII !11IIIHNNB@RRRRR 'xpپ};>`;(`-D| S _4!`(&MoHT<yN 뇵XјBUO!2y )))8ǎCkk+N'zzzK.E󡣣v=n7yf|ǂ󡦦Drr2^/\.ap8 ۍ8vp 55:u :;L?W_Xz94zIJl_HDBaiilSM&S,|ZʪF1~0L ۱b;qO/2 RZZZv(JD"|'X~¾}O? T+~7n{_č7ވ & hllc=&ٲe jkk>)---pݸqC+֯_?Xp!)S"I&7K/$J%:::L>̐1ynL&`0|mX(XZ!϶!|`430V}s!wv8l>_,Įே( .%%eeeqF|+o_'77[jr^vnJb1'8܌3>͛j@.bNr຺8rmmmܖ-[;S(cSSSUVq.K]s5.990a€zΘ1áLFZ4CillThEEEᬳBU;yyz3>:p)g6n3ghy!//w^yc999u<>b.\F[Fx-kq=d^+2 t:>'N˱nݺaE{bҥ׿{_,_\peP(;P[[HJJD"={l2^͛7Cb׮]t{gիWaJT*qu᭷SO=Lr8NPSwr%p0B#h*GR(,*AP(BC h-oQ Xyb!D|Ť4aچδx^8q8z(^z%,XO>$X2D]]j5}?..{/^xn=P(/;@|||P<3Xz59rNՅ> Z=]t)}!-C" ˗/DŽ  t:Os.|>mۆ{ع[m}(+A˲s.FZ wi+QG$YBla2Yx @x2q?"|& qqqH$p\x衇FmL%`^455 RHJJCkk+ۃ n7|> =8zʕ5KNNNbKd2eIHE}[i BҚ}$*Նъ*eYz-;;h$aĉ5 C >F mE &J8^7(: !HxǏC&W_-h˥';pAC"^---8}4>`NKB HjqI^4iR0\okke2BZx^}Ué0e|rօ8q[c-az)"C!(ٖ CFh4ҙ3gnĠAkk+N.R\O[[ڊ68\ۭ2555Vz5̓/db#D@ְ0U=|7daPQQɓ'ZjՊiӦBX,H$O~a f~a'r\ 1o޼+!!W]uUPH$M'OO,[* pe@>!BČt>|e&a焐ay4 Q˗{|㦭[n9s'FIHLLRZ3f _,5'OF|||H떙 #+3+$`{`0:M@(oR^B 6"n|?Z?FK#,Xe[x8D3Xɓ'A㑕5̙r2}td!7x^?]zB^_V8Ch, wn@fhnlhh($-A @`i# |>:u*Fggȕ0k񡷷W\\Y^vxal.@  N lWqF4ζcqW|#_D].ZZZB.rXq_|PѦb#TCC\ B # %y(t@#A #a 2 >*`|W8|0ry09A,X,_'N9--- ( V UKX%bP0X{bhU̙3&^oO>A[[[~!N>}F&׋l6|!kN|'a磨M b٦j4x3iB MӍH b=B|Ȏn D. ^/{|>b޽|AH7`ƍd#)) JP(HIIAjjjgqqqHJJ?mӦM/!73gζp>}9SUUUe&MB^}H#R&5cZ"?21!:O"$poy#n؂~_J;;;L&߿_bݺu8tzvvap8p8 Ӊnx<`ӦMoSN᭷ނnGBB`?kiiiuD! [X01bI+ [󙓨H k٦I@+HPˣX!{*x B-@d~u\HJJ|GذaC0;lڴ F ɓ'ى$\yo5k_}݇^qXf >#AbxwC15Bu84Mב [3ӨT$=V0b02b=!!u"$!;{93N'&L+~a9-[=9ޔ_WOnJ2xӃÇcxWgtvvb׮]X|9b1~n۷cݺuzHII f͚{ʢ7Fc!%, hcY`/FՆ;#ѢӨXFMg~c"1:"oP@$!Z<;;;!J!pQ %XP(>!* 0uuuKF{uhJUTTOh4 Ng 4L&RP/ݩjsq5HtHxv>vŪR6=0 c0a60Z!Dp;We]MM5Fr@1ZO] ȿȏ$AA0?"-ŋ7Yazq1@VVa{aѢE(,,m݆|g?wߍz*<`8Yf%>-4Lnpmnã> ,Z7x# QQQ}A,#-- J2aKeѢE~k"i^^^^bPeRD[LQ0\vceuPTuC'(W*^8>[X@\|;0 ;DF1E 1NW1~(KJJ;FAN6撒}aD$(L}$|=tC$>QHZ"$u'ODBB&M4$&&vcϞ=رcv܉r(JL<IIIpݘ4it:RDUUnx^H$L0b/^:o&vڅ'O">>'NDFFn7N<3kH:0 &BoF_oEӴ"2`x}єᘩj+)jI'PnCỿ},,cѻO{;TJU5V7 Lt$lHp !F^W<]KJJT1!k:n n?aP˄#wijjjJr qhiit:q )) Rp:\?nAN8!>>0aӑ L8p88q`X|W"Q|a6B5*(!RUUUe]0U"IjuHf; QH U>Z6 @ݮ;˲JFS~Z+P s,*Ap>_ #ҝ(,{$!DHCN,9`Cn"D*0x,x㦦&4NL&Cww70|H$oMzĩS҂VԩS8}4ZZZt:[<5kXM&SBhf_?_γ21Ă 65_mu:z_ "x@}TEEEy8̱,d|+js °G_?`upQ_#1%([E @pPVKHǘ >}zotmmmW_H_22 4Mk Y=pu@ÑSRR<#/Tرnes׮]{[NNwIO dee 1D̑+^ً/t^ /mUVkkkC%B اrssi Bd2 sssFS}uTFca(,EjV{  zKUUU T*6כ2C1Zme( =>ıe0ETqqqm(| 3oh p:D OY~򀐨?O n^@̄ ɱ?`Yi;wO>d~!c2Ξ=r"^]mNNNS0 E1:X+ w_l{t!6nvsXV"jHn7~駰X,|.xUjl6egg 1=VBgR4l  Xʪo2M\Zތm4M+++=0$&aa&BT-:hE-a5/ >MM;q֯_ۍͭs6gVV5/!#D)z򾌙QTlC0mXh4&b 555V:D!c~ᡏ EìYv!qQp\^~! ))iAnnnx_\6# Qfy@pK5//oS)"ckdc< {`>h1HUXE~(" 5FJVZ[['?chټy3L&<RSS9ǫc0:ؘ/$a4Mfs^">bo999Mf9&x\bY DHNN_TXSu!bR!b F2}i ǃ$$$<~f,?+[nŲe˰cD"$&&}# E˲X +xKP!#D5'')"jscccn;Jm!|JU΋'~8T`!fcBdZ`qjT B-Q-@3 viiid8~8y;p#>-[tRܹ 1@\{,X Ɂt:nω=־8q4BnDBkmmm11#0cR|DT__w.daUP4UķP ΅8 M(P"^ `~=R1WP"hXquꫯ;H$nʔ)L&pYYYܯk/|>7?Εr\rIYYY\bb"ZFhlpFe^^@ "TSVVinhllT q%//inɩm.++}sNHHJUCsNNN]4"˃?6mh\GG18ڵW\I$&>x)**[GP(P,؆*TvvvC *@-Yްa=9'' =Gb466*P7%$ jDHI19.J@Ǵ8 ႂ?aEzAUAAAU,O~j3M-)_l\.Ҹ'r܄ 'r\zz:p։п B(Hb,#hHHXWҧkB1"cF$ 6EEEXE %RH!Q,{WUWWٳgDňo8"?*uʔ)GKKKx≷Ȏa6)v%˲0w2azRii֬`2heiٜ?ܶ>BQ(+MӍH~J2\P(4M~mfLXUfe\Joni(0L=0f $&HTWW:uj"9XxjjjVG@ @ 䜬Y掇~!'x_/+@  7ߜ[]]]}kx 媫3X@ DeY%|>H$H$y<W^y<@  @ !& @ D@ "@@ aU]iIENDB`celluloid-io-0.16.2/LICENSE.txt0000644000004100000410000000205512477620141016042 0ustar www-datawww-dataCopyright (c) 2012 Tony Arcieri MIT License Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. celluloid-io-0.16.2/spec/0000755000004100000410000000000012477620141015147 5ustar www-datawww-datacelluloid-io-0.16.2/spec/spec_helper.rb0000644000004100000410000000400112477620141017760 0ustar www-datawww-datarequire 'rubygems' require 'bundler/setup' require 'celluloid/io' require 'celluloid/rspec' require 'coveralls' Coveralls.wear! logfile = File.open(File.expand_path("../../log/test.log", __FILE__), 'a') logfile.sync = true logger = Celluloid.logger = Logger.new(logfile) Celluloid.shutdown_timeout = 1 RSpec.configure do |config| config.filter_run :focus => true config.run_all_when_everything_filtered = true config.before do Celluloid.logger = logger Celluloid.shutdown Celluloid.boot FileUtils.rm("/tmp/cell_sock") if File.exist?("/tmp/cell_sock") end end class ExampleActor include Celluloid::IO execute_block_on_receiver :wrap def wrap yield end end EXAMPLE_PORT = 12345 def example_addr; '127.0.0.1'; end def example_port; EXAMPLE_PORT; end def example_unix_sock; '/tmp/cell_sock'; end def example_ssl_port; EXAMPLE_PORT + 1; end def fixture_dir; Pathname.new File.expand_path("../fixtures", __FILE__); end def within_io_actor(&block) actor = ExampleActor.new actor.wrap(&block) ensure actor.terminate if actor.alive? end def with_tcp_server server = Celluloid::IO::TCPServer.new(example_addr, example_port) begin yield server ensure server.close end end def with_unix_server server = Celluloid::IO::UNIXServer.open(example_unix_sock) begin yield server ensure server.close File.delete(example_unix_sock) end end def with_connected_sockets with_tcp_server do |server| # FIXME: client isn't actually a Celluloid::IO::TCPSocket yet client = ::TCPSocket.new(example_addr, example_port) peer = server.accept begin yield peer, client ensure begin client.close peer.close rescue end end end end def with_connected_unix_sockets with_unix_server do |server| client = Celluloid::IO::UNIXSocket.new(example_unix_sock) peer = server.accept begin yield peer, client ensure begin client.close peer.close rescue end end end end celluloid-io-0.16.2/spec/fixtures/0000755000004100000410000000000012477620141017020 5ustar www-datawww-datacelluloid-io-0.16.2/spec/fixtures/client.crt0000644000004100000410000000243612477620141021015 0ustar www-datawww-data-----BEGIN CERTIFICATE----- MIIDmjCCAoICCQDwZ8yE/0n4PjANBgkqhkiG9w0BAQUFADCBjjELMAkGA1UEBhMC VVMxEzARBgNVBAgTCkNhbGlmb3JuaWExFjAUBgNVBAcTDVNhbiBGcmFuY2lzY28x EjAQBgNVBAoTCUNlbGx1bG9pZDEbMBkGA1UEAxMSY2xpZW50LmV4YW1wbGUuY29t MSEwHwYJKoZIhvcNAQkBFhJjbGllbnRAZXhhbXBsZS5jb20wHhcNMTIxMTI1MTkx NjI2WhcNMjIxMTIzMTkxNjI2WjCBjjELMAkGA1UEBhMCVVMxEzARBgNVBAgTCkNh bGlmb3JuaWExFjAUBgNVBAcTDVNhbiBGcmFuY2lzY28xEjAQBgNVBAoTCUNlbGx1 bG9pZDEbMBkGA1UEAxMSY2xpZW50LmV4YW1wbGUuY29tMSEwHwYJKoZIhvcNAQkB FhJjbGllbnRAZXhhbXBsZS5jb20wggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEK AoIBAQDV6zzpkAIX4FijnytX84GgHb8hYdNJAn+9g57XGrqtAH6BlLoANFl4n/+y nEQwBqlrNnfstPrf7sPezytntSVyufSE+LGUGBJA/jyjQCMcEe8+4bfOC2ZhCpvn I2dKNKwsmM+DyWs/PVl7XEAZF2P4iQ8eGLVFjph+KA/D79cHkIeGt4FEA4xJWqKf +Kjftxo1cBqLx2dUiucRL7tva3ingAqYSs/i82jKLGlj7fdRMytOx87Nhs35RWpu 66l7hvpetx3t2wU2obKOzKhS4ycaZ2AptEDNXKaBTQ5lejSRxFBCpYQtqmkd0bMG /T5ZfXC45axj9a2rj8AKZct+mLCzAgMBAAEwDQYJKoZIhvcNAQEFBQADggEBAHzr b4VTktAi+8baGRJCXupt0Ari8ffoWhsYerELFLQF7K2sluxOqCsGEEF21e99fZxP lisLi0DIQ7cNlOGjRJ3xaydE74Fsry3xBNKoR8I7OMr9VFsrC54tc0x7NQ7bRHy6 kCjSwKN4I2KWJjQ8yf8mIalmUKOmb/hirzna8io4CiDeJGZ1XNAQ9dl1RHRW442G GTu2ofAtU8TlzilZyclMY/lN7whw7sKP+pPr6fpAOJZsR64IzbBcWHHjJhx70XOx jnd5FB1oXnuupgPqEKmatSCytrue8GTkanB8VZ6+Zd/4XgTkie3UtCZW8R+NL/Lo us/+Ks3WIDyYdPSPnbE= -----END CERTIFICATE----- celluloid-io-0.16.2/spec/fixtures/client.key0000644000004100000410000000321712477620141021013 0ustar www-datawww-data-----BEGIN RSA PRIVATE KEY----- MIIEpAIBAAKCAQEA1es86ZACF+BYo58rV/OBoB2/IWHTSQJ/vYOe1xq6rQB+gZS6 ADRZeJ//spxEMAapazZ37LT63+7D3s8rZ7Ulcrn0hPixlBgSQP48o0AjHBHvPuG3 zgtmYQqb5yNnSjSsLJjPg8lrPz1Ze1xAGRdj+IkPHhi1RY6YfigPw+/XB5CHhreB RAOMSVqin/io37caNXAai8dnVIrnES+7b2t4p4AKmErP4vNoyixpY+33UTMrTsfO zYbN+UVqbuupe4b6Xrcd7dsFNqGyjsyoUuMnGmdgKbRAzVymgU0OZXo0kcRQQqWE LappHdGzBv0+WX1wuOWsY/Wtq4/ACmXLfpiwswIDAQABAoIBAQCFDDcpaUj0ArP+ qEuz+x6/MGEk6QwZV7WNcGSFkvlSCoGkJJV+9RBExvao5yo92JbcuNbj4Tg7uOwY EzAC45a0AVZEscz4t/P6emXKf2SW28y6hnbkbxCxAIEwxENE0vfXEP/YDplmjsit whWXxYWHGe/OHz33UhYkONR9YBmUeLrtloRNUV82XDSpn4d7toLKaZW2kOFl4nFR SQ3pDPk1hleG8AZcfnF2LwaPx1XjPwBnXY9FK2jyNupVghfCw/Sv91dbbVkkIG14 A8WpZKAXjXXOcTroof5+NJSPXzYrRuvP8K6H2zGj7F/AsP4hiZqGkb4tel0yH5VM oLCUTHqhAoGBAPysxeoT1ytajQ55UV1yjsnQ3jF9YcWsZwPEJgMI+bt+QzAfqqZs Kuvg8Gi7ukbcc2pKwXv+ma9HLJq/pQbWlfxcMNulY0VCPY/ceaPen+EfCJTApVpY YFS25i/JnIp9IudpQBuLHz9Yy4f1W2VoeG/mFqOmUxiTx4LM87G6rdtDAoGBANi7 5raiwDS+rD91l5FLq3kdvgSDgYk4hh7BBJNJt8vhJYInIev5eb/Z41X8PfqWa2ir 9aanpMYhWDJxbdSQDd3/op6jtOZM7InLceAm2O29VY2+HW5ePpc21AHsqoZpFYEZ YP8xvbSjJzfkrYr4y+aAMXONVAi4afqG7x6GqCXRAoGBAPbzFWu1gHKKyZn/0Bn4 wL1WOhM8a7Z6zSPNLSmCODGbMadzC6Ijzb9D1TNHZsOi6dpUvc2mBCZe9aU48N1C FMzUfZvuhJtIJkrYPLp/9tpbLlPUBMfL4Dprl4XVEf34V4i8QT+qNRwAeMukbXMr K6qRwkanZEd9B107WmG2Bf1pAoGACpld1g6tgabVe6D/kY52y0yGD2hy/Ef0Xyqn U6CmSWUwVWYehZDEwHoiYQEd8tRKWmsWb1kBeOMGkijz6xJEa1fmFwYAgca/RpnZ btHXiADbXzwt6kjXnMOEqLdvO3WGJLMeCDzhfyT/dP9M8V/rcNFSGcmOk4KZRDQ3 G3IQZRECgYBqHqvxHeL087UHXE1tdAGFVfxOiYE1afksJbkV06VnO8XXr9sNSWwy YjXVY9k6U1BFo7jHrWr6TkeMkB45wyn/fasHKU7qsPt0joRFkXMCzwl376hto3Tg RGXQCA4RUQXkxaDctJ5TgcF7MhK7tAFd1aBVlxwGENLYUVL0ZPaMrw== -----END RSA PRIVATE KEY----- celluloid-io-0.16.2/spec/fixtures/server.crt0000644000004100000410000000243612477620141021045 0ustar www-datawww-data-----BEGIN CERTIFICATE----- MIIDmjCCAoICCQD+dJ16wNIKnzANBgkqhkiG9w0BAQUFADCBjjELMAkGA1UEBhMC VVMxEzARBgNVBAgTCkNhbGlmb3JuaWExFjAUBgNVBAcTDVNhbiBGcmFuY2lzY28x EjAQBgNVBAoTCUNlbGx1bG9pZDEbMBkGA1UEAxMSc2VydmVyLmV4YW1wbGUuY29t MSEwHwYJKoZIhvcNAQkBFhJzZXJ2ZXJAZXhhbXBsZS5jb20wHhcNMTIxMTI1MTkx NjAwWhcNMjIxMTIzMTkxNjAwWjCBjjELMAkGA1UEBhMCVVMxEzARBgNVBAgTCkNh bGlmb3JuaWExFjAUBgNVBAcTDVNhbiBGcmFuY2lzY28xEjAQBgNVBAoTCUNlbGx1 bG9pZDEbMBkGA1UEAxMSc2VydmVyLmV4YW1wbGUuY29tMSEwHwYJKoZIhvcNAQkB FhJzZXJ2ZXJAZXhhbXBsZS5jb20wggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEK AoIBAQCpLs3Xg00RtoG4+SKaaNfw6Dve9d0Kkg0CNfU8AsxOgTIU1Qu8s+bzKkqe 66NfCa6T8VPpk9VbIlF2ONdgY4o8muV1q+mS6j2HDAtWPiDjP+9YOwGf/DT3LhSb g8k+alL2cqe7B1XNUsNFEvQ+yQLlj9MWKb7nbYDM8aqdv46KGoDj9v9rfm4QiKwI B6u/KoQG22YF7sT4O44jU/u20xcm3rV1Elg0gC/UP/YqnuMPCZYcK/Z9vYGtDJ6G 8OYDcPZSZBdkqlffhYBssSj3R7sTCqoh4ms08ukcGycbvUO+cWrPKnmySsGaCYtG kp7QsH1ec7QGA01hZL2yL8CuJMUbAgMBAAEwDQYJKoZIhvcNAQEFBQADggEBABE4 gYVSdC87NhpA49k0vcLLU7v7mU3a3no/vu1CIqQxzx8/xh26Qi3aGb1s9MgHpF2Z NiB1irXER2tyz/F3qCi8OCo7eNsndmDjj4GnkBjEPTtqRxH9imRWw4bJyqwqFHcu 1kczCZa+2VFQFEL4ErGycPFKM59ppTcJ0IxbK7PCGzO75TRQoAl52+3Aob+oejPP qFbiqNlV1T3EKa5yLdvOC5sLrEcfm3iMxmOtNVzp9OBhjXfm8Q1zgYs4VyJXzLMK wf956w2YEbpTAAzNc53zly/Jhr4MnFsa9Mn1oYp9Rfjzw/qJtXw+a3PtEKrO4XNe TsKHsAkj8XvUrhliiNQ= -----END CERTIFICATE----- celluloid-io-0.16.2/spec/fixtures/server.key0000644000004100000410000000321312477620141021037 0ustar www-datawww-data-----BEGIN RSA PRIVATE KEY----- MIIEogIBAAKCAQEAqS7N14NNEbaBuPkimmjX8Og73vXdCpINAjX1PALMToEyFNUL vLPm8ypKnuujXwmuk/FT6ZPVWyJRdjjXYGOKPJrldavpkuo9hwwLVj4g4z/vWDsB n/w09y4Um4PJPmpS9nKnuwdVzVLDRRL0PskC5Y/TFim+522AzPGqnb+OihqA4/b/ a35uEIisCAervyqEBttmBe7E+DuOI1P7ttMXJt61dRJYNIAv1D/2Kp7jDwmWHCv2 fb2BrQyehvDmA3D2UmQXZKpX34WAbLEo90e7EwqqIeJrNPLpHBsnG71DvnFqzyp5 skrBmgmLRpKe0LB9XnO0BgNNYWS9si/AriTFGwIDAQABAoIBAGKRoV4p4rIqOiQy CuYZpY53T8KUToeFFk0ucMXY/33RqgMXKTJ1Ql50SmuS8GlDs9IALZqOBiWFth6B +YHwHK84s+2+DmUJUnWnH8fMhM7CBknKfyTeBWHqGBmPS6WwvstVe8HtASGSUbCh 3WnjJWvoQtzLz6z4UK2XM4ea/ooY+hlcw6DM+jZuTstzLFE/9BPoHueaW8UemjaH ZUXMKm3+I3iIjHszUUWM59bS9pOBn/YvIJbVE5wMIVCP2YXDCgfpV2Z4nDiAHppn fnha2TzHzlPMgwhBpz06r6G8X+A6gJl98TDSK41nIMyXqiZ2aoALL3UOssAMfUHr 2y9CGdECgYEA27F1IyUW3JgqCeqZ7eCeT4emhAvyohzM5pzWI7C8ZosF14zFRpek TgmjdTGMQ1EZVVkyj85RyvMm3MkcKOHetc5g2jJg3EkxvAV+PMs7yjpqg3itEjC6 vIhXLoXdq+FuruA2h4O0hi6yuf1FCQYtpNLTe49qetjsaWzwwowHwlMCgYEAxSRo k+AdpoNXblnIhd0EaKjGAsHFrC039o7JqQe/mKAiXaGiidIDk5Vt/ChT6Qa6fiLq cdysCn+tSCt/DdRrELZohc0ipuy5/agQmJgWoW7oay8ldzxHP9VevWo4UuqVudW9 evhKe0a9uXCrSimvZ5PJk91lmBx92FBeP6Y+qRkCgYAXQsvPQ88O3kGdOSzBJgY9 D3TPCGDRT1FWnYaC0uSvysp8jxgYKFgqNxUKhIuAWSbghYg397VrUqFrwRNtNLUa 9NYGZE0jJdDRQpeiIjaba+H5N57DjUtISPtKHrxgxYatl2nOoWBM0Mb1sF5N3UyZ 5gSkUYQJq8wkQXegcakkpwKBgEdvvgV3vMbN6SyvlB4NzL8wCTCOjtapPBI4A5Mg n6jqvgk3vPI8C9e62jP5WQ6jxYhXlqTT1fOn+F6ihFO6mWFg99ckUl4ygeMMt5bT 5b9xtP7CAs2GJjtXUhFJIEfLgZ3pedPJjRPGupEr5qXlHQ5nWzAdlebczC1KUhy2 XRZhAoGAGA3SAAF79PK3c3+bOOviXxDFuH5TCBmbtEpJ+/jCbwR6Z8fMRswZJ3Gc l8eNMsB+Kfif+806xAgLxsyhYuyvF6rE/V34GKjW22T1gwk6gY/rOgFn42jo8lwl HFbSB+IG0+Go0m+0QmyRh7SyPvDNtyYzBFFdl9U8JYYGM0Nfgd0= -----END RSA PRIVATE KEY----- celluloid-io-0.16.2/spec/celluloid/0000755000004100000410000000000012477620141017123 5ustar www-datawww-datacelluloid-io-0.16.2/spec/celluloid/io/0000755000004100000410000000000012477620141017532 5ustar www-datawww-datacelluloid-io-0.16.2/spec/celluloid/io/ssl_server_spec.rb0000644000004100000410000000533012477620141023261 0ustar www-datawww-datarequire 'spec_helper' describe Celluloid::IO::SSLServer do let(:client_cert) { OpenSSL::X509::Certificate.new fixture_dir.join("client.crt").read } let(:client_key) { OpenSSL::PKey::RSA.new fixture_dir.join("client.key").read } let(:client_context) do OpenSSL::SSL::SSLContext.new.tap do |context| context.cert = client_cert context.key = client_key end end let(:server_cert) { OpenSSL::X509::Certificate.new fixture_dir.join("server.crt").read } let(:server_key) { OpenSSL::PKey::RSA.new fixture_dir.join("server.key").read } let(:server_context) do OpenSSL::SSL::SSLContext.new.tap do |context| context.cert = server_cert context.key = server_key end end describe "#accept" do let(:payload) { 'ohai' } context "inside Celluloid::IO" do it "should be evented" do with_ssl_server do |subject| within_io_actor { Celluloid::IO.evented? }.should be_true end end it "accepts a connection and returns a Celluloid::IO::SSLSocket" do with_ssl_server do |subject| thread = Thread.new do raw = TCPSocket.new(example_addr, example_ssl_port) OpenSSL::SSL::SSLSocket.new(raw, client_context).connect end peer = within_io_actor { subject.accept } peer.should be_a Celluloid::IO::SSLSocket client = thread.value client.write payload peer.read(payload.size).should eq payload end end end context "outside Celluloid::IO" do it "should be blocking" do with_ssl_server do |subject| Celluloid::IO.should_not be_evented end end it "accepts a connection and returns a Celluloid::IO::SSLSocket" do with_ssl_server do |subject| thread = Thread.new do raw = TCPSocket.new(example_addr, example_ssl_port) OpenSSL::SSL::SSLSocket.new(raw, client_context).connect end peer = subject.accept peer.should be_a Celluloid::IO::SSLSocket client = thread.value client.write payload peer.read(payload.size).should eq payload end end end end describe "#initialize" do it "should auto-wrap a raw ::TCPServer" do raw_server = ::TCPServer.new(example_addr, example_ssl_port) with_ssl_server(raw_server) do |ssl_server| ssl_server.tcp_server.class.should == Celluloid::IO::TCPServer end end end def with_ssl_server(raw_server = nil) raw_server ||= Celluloid::IO::TCPServer.new(example_addr, example_ssl_port) server = Celluloid::IO::SSLServer.new(raw_server, server_context) begin yield server ensure server.close end end end celluloid-io-0.16.2/spec/celluloid/io/tcp_socket_spec.rb0000644000004100000410000001437212477620141023236 0ustar www-datawww-datarequire 'spec_helper' describe Celluloid::IO::TCPSocket do let(:payload) { 'ohai' } context "inside Celluloid::IO" do describe ".open" do it "returns the open socket" do server = ::TCPServer.new example_addr, example_port thread = Thread.new { server.accept } socket = within_io_actor { Celluloid::IO::TCPSocket.open(example_addr, example_port) } socket.should be_a(Celluloid::IO::TCPSocket) server.close thread.terminate socket.close end context "when passed a block" do it "returns the block evaluation" do server = ::TCPServer.new example_addr, example_port thread = Thread.new { server.accept } value = within_io_actor { Celluloid::IO::TCPSocket.open(example_addr, example_port) { true } } value.should be_true server.close thread.terminate end end end it "connects to TCP servers" do server = ::TCPServer.new example_addr, example_port thread = Thread.new { server.accept } socket = within_io_actor { Celluloid::IO::TCPSocket.new example_addr, example_port } peer = thread.value peer << payload within_io_actor { socket.read(payload.size) }.should eq payload server.close socket.close peer.close end it "should be evented" do with_connected_sockets do |subject| within_io_actor { Celluloid::IO.evented? }.should be_true end end it "read complete payload when nil size is given to #read" do with_connected_sockets do |subject, peer| peer << payload within_io_actor { subject.read(nil) }.should eq payload end end it "read complete payload when no size is given to #read" do with_connected_sockets do |subject, peer| peer << payload within_io_actor { subject.read }.should eq payload end end it "reads data" do with_connected_sockets do |subject, peer| peer << payload within_io_actor { subject.read(payload.size) }.should eq payload end end it "reads data in binary encoding" do with_connected_sockets do |subject, peer| peer << payload within_io_actor { subject.read(payload.size).encoding }.should eq Encoding::BINARY end end it "reads partial data" do with_connected_sockets do |subject, peer| peer << payload * 2 within_io_actor { subject.readpartial(payload.size) }.should eq payload end end it "reads partial data in binary encoding" do with_connected_sockets do |subject, peer| peer << payload * 2 within_io_actor { subject.readpartial(payload.size).encoding }.should eq Encoding::BINARY end end it "writes data" do with_connected_sockets do |subject, peer| within_io_actor { subject << payload } peer.read(payload.size).should eq payload end end it "raises Errno::ECONNREFUSED when the connection is refused" do expect { within_io_actor { ::TCPSocket.new(example_addr, example_port) } }.to raise_error(Errno::ECONNREFUSED) end context 'eof?' do it "blocks actor then returns by close" do with_connected_sockets do |subject, peer| started_at = Time.now Thread.new{ sleep 0.5; peer.close; } within_io_actor { subject.eof? } (Time.now - started_at).should > 0.5 end end it "blocks until gets the next byte" do with_connected_sockets do |subject, peer| peer << 0x00 peer.flush expect { within_io_actor { subject.read(1) Celluloid.timeout(0.5) { subject.eof?.should be_false } } }.to raise_error(Celluloid::Task::TimeoutError) end end end context "readpartial" do it "raises EOFError when reading from a closed socket" do with_connected_sockets do |subject, peer| peer.close expect { within_io_actor { subject.readpartial(payload.size) } }.to raise_error(EOFError) end end it "raises IOError when active sockets are closed across threads" do pending "not implemented" with_connected_sockets do |subject, peer| actor = ExampleActor.new begin read_future = actor.future.wrap do subject.readpartial(payload.size) end sleep 0.1 subject.close expect { read_future.value 0.25 }.to raise_error(IOError) ensure actor.terminate if actor.alive? end end end it "raises IOError when partial reading from a socket the peer closed" do pending "async block running on receiver" with_connected_sockets do |subject, peer| actor = ExampleActor.new begin actor.async.wrap { sleep 0.01; peer.close } expect do within_io_actor { subject.readpartial(payload.size) } end.to raise_error(IOError) ensure actor.terminate if actor.alive? end end end end end context "outside Celluloid::IO" do it "connects to TCP servers" do server = ::TCPServer.new example_addr, example_port thread = Thread.new { server.accept } socket = Celluloid::IO::TCPSocket.new example_addr, example_port peer = thread.value peer << payload socket.read(payload.size).should eq payload server.close socket.close peer.close end it "should be blocking" do with_connected_sockets do |subject| Celluloid::IO.should_not be_evented end end it "reads data" do with_connected_sockets do |subject, peer| peer << payload subject.read(payload.size).should eq payload end end it "reads partial data" do with_connected_sockets do |subject, peer| peer << payload * 2 subject.readpartial(payload.size).should eq payload end end it "writes data" do with_connected_sockets do |subject, peer| subject << payload peer.read(payload.size).should eq payload end end end end celluloid-io-0.16.2/spec/celluloid/io/reactor_spec.rb0000644000004100000410000000162012477620141022527 0ustar www-datawww-datarequire 'spec_helper' describe Celluloid::IO::Reactor do let(:payload) { "balls" } it "shouldn't crash" do server = ::TCPServer.new example_addr, example_port thread = Thread.new { server.accept } socket = within_io_actor { Celluloid::IO::TCPSocket.new example_addr, example_port } peer = thread.value peer_thread = Thread.new { loop { peer << payload } } handle = false # Main server body: within_io_actor do begin timeout(2) do loop do socket.readpartial(2046) end end # rescuing timeout, ok. rescuing terminated error, is it ok? TODO: investigate rescue Celluloid::Task::TerminatedError, Timeout::Error ensure socket.readpartial(2046) handle = true end end expect(handle).to be_true server.close peer.close socket.close end end celluloid-io-0.16.2/spec/celluloid/io/mailbox_spec.rb0000644000004100000410000000014612477620141022525 0ustar www-datawww-datarequire 'spec_helper' describe Celluloid::IO::Mailbox do it_behaves_like "a Celluloid Mailbox" end celluloid-io-0.16.2/spec/celluloid/io/tcp_server_spec.rb0000644000004100000410000000276312477620141023255 0ustar www-datawww-datarequire 'spec_helper' describe Celluloid::IO::TCPServer do describe "#accept" do let(:payload) { 'ohai' } it "can be initialized without a host" do expect { Celluloid::IO::TCPServer.new(2000).close }.to_not raise_error end context "inside Celluloid::IO" do it "should be evented" do with_tcp_server do |subject| within_io_actor { Celluloid::IO.evented? }.should be_true end end it "accepts a connection and returns a Celluloid::IO::TCPSocket" do with_tcp_server do |subject| thread = Thread.new { TCPSocket.new(example_addr, example_port) } peer = within_io_actor { subject.accept } peer.should be_a Celluloid::IO::TCPSocket client = thread.value client.write payload peer.read(payload.size).should eq payload end end context "outside Celluloid::IO" do it "should be blocking" do with_tcp_server do |subject| Celluloid::IO.should_not be_evented end end it "accepts a connection and returns a Celluloid::IO::TCPSocket" do with_tcp_server do |subject| thread = Thread.new { TCPSocket.new(example_addr, example_port) } peer = subject.accept peer.should be_a Celluloid::IO::TCPSocket client = thread.value client.write payload peer.read(payload.size).should eq payload end end end end end end celluloid-io-0.16.2/spec/celluloid/io/unix_server_spec.rb0000644000004100000410000000370412477620141023446 0ustar www-datawww-datarequire 'spec_helper' describe Celluloid::IO::UNIXServer do describe "#accept" do before do pending "JRuby support" if defined?(JRUBY_VERSION) end let(:payload) { 'ohai' } context "inside Celluloid::IO" do it "should be evented" do with_unix_server do |subject| within_io_actor { Celluloid::IO.evented? }.should be_true end end it "accepts a connection and returns a Celluloid::IO::UNIXSocket" do with_unix_server do |subject| thread = Thread.new { UNIXSocket.new(example_unix_sock) } peer = within_io_actor { subject.accept } peer.should be_a Celluloid::IO::UNIXSocket client = thread.value client.write payload peer.read(payload.size).should eq payload end end it "raises if server already up" do with_unix_server do |subject| within_io_actor do expect { Celluloid::IO::UNIXServer.open(example_unix_sock) }.to raise_error(Errno::EADDRINUSE) end end end context "outside Celluloid::IO" do it "should be blocking" do with_unix_server do |subject| Celluloid::IO.should_not be_evented end end it "accepts a connection and returns a Celluloid::IO::UNIXSocket" do with_unix_server do |subject| thread = Thread.new { UNIXSocket.new(example_unix_sock) } peer = subject.accept peer.should be_a Celluloid::IO::UNIXSocket client = thread.value client.write payload peer.read(payload.size).should eq payload end end it "raises if server already up" do with_unix_server do |subject| expect { Celluloid::IO::UNIXServer.open(example_unix_sock) }.to raise_error(Errno::EADDRINUSE) end end end end end end celluloid-io-0.16.2/spec/celluloid/io/unix_socket_spec.rb0000644000004100000410000001106712477620141023431 0ustar www-datawww-datarequire 'spec_helper' describe Celluloid::IO::UNIXSocket do before do pending "JRuby support" if defined?(JRUBY_VERSION) end let(:payload) { 'ohai' } context "inside Celluloid::IO" do it "connects to UNIX servers" do server = ::UNIXServer.open example_unix_sock thread = Thread.new { server.accept } socket = within_io_actor { Celluloid::IO::UNIXSocket.open example_unix_sock } peer = thread.value peer << payload within_io_actor { socket.read(payload.size) }.should eq payload server.close socket.close peer.close File.delete(example_unix_sock) end it "should be evented" do with_connected_unix_sockets do |subject| within_io_actor { Celluloid::IO.evented? }.should be_true end end it "read complete payload when nil size is given to #read" do with_connected_unix_sockets do |subject, peer| peer << payload within_io_actor { subject.read(nil) }.should eq payload end end it "read complete payload when no size is given to #read" do with_connected_unix_sockets do |subject, peer| peer << payload within_io_actor { subject.read }.should eq payload end end it "reads data" do with_connected_unix_sockets do |subject, peer| peer << payload within_io_actor { subject.read(payload.size) }.should eq payload end end it "reads data in binary encoding" do with_connected_unix_sockets do |subject, peer| peer << payload within_io_actor { subject.read(payload.size).encoding }.should eq Encoding::BINARY end end it "reads partial data" do with_connected_unix_sockets do |subject, peer| peer << payload * 2 within_io_actor { subject.readpartial(payload.size) }.should eq payload end end it "reads partial data in binary encoding" do with_connected_unix_sockets do |subject, peer| peer << payload * 2 within_io_actor { subject.readpartial(payload.size).encoding }.should eq Encoding::BINARY end end it "writes data" do with_connected_unix_sockets do |subject, peer| within_io_actor { subject << payload } peer.read(payload.size).should eq payload end end it "raises Errno::ENOENT when the connection is refused" do expect { within_io_actor { Celluloid::IO::UNIXSocket.open(example_unix_sock) } }.to raise_error(Errno::ENOENT) end it "raises EOFError when partial reading from a closed socket" do with_connected_unix_sockets do |subject, peer| peer.close expect { within_io_actor { subject.readpartial(payload.size) } }.to raise_error(EOFError) end end context 'eof?' do it "blocks actor then returns by close" do with_connected_sockets do |subject, peer| started_at = Time.now Thread.new{ sleep 0.5; peer.close; } within_io_actor { subject.eof? } (Time.now - started_at).should > 0.5 end end it "blocks until gets the next byte" do with_connected_sockets do |subject, peer| peer << 0x00 peer.flush expect { within_io_actor { subject.read(1) Celluloid.timeout(0.5) { subject.eof?.should be_false } } }.to raise_error(Celluloid::Task::TimeoutError) end end end end context "outside Celluloid::IO" do it "connects to UNIX servers" do server = ::UNIXServer.new example_unix_sock thread = Thread.new { server.accept } socket = Celluloid::IO::UNIXSocket.open example_unix_sock peer = thread.value peer << payload socket.read(payload.size).should eq payload server.close socket.close peer.close File.delete example_unix_sock end it "should be blocking" do with_connected_unix_sockets do |subject| Celluloid::IO.should_not be_evented end end it "reads data" do with_connected_unix_sockets do |subject, peer| peer << payload subject.read(payload.size).should eq payload end end it "reads partial data" do with_connected_unix_sockets do |subject, peer| peer << payload * 2 subject.readpartial(payload.size).should eq payload end end it "writes data" do with_connected_unix_sockets do |subject, peer| subject << payload peer.read(payload.size).should eq payload end end end end celluloid-io-0.16.2/spec/celluloid/io/ssl_socket_spec.rb0000644000004100000410000001431212477620141023243 0ustar www-datawww-datarequire 'spec_helper' require 'openssl' describe Celluloid::IO::SSLSocket do let(:request) { 'ping' } let(:response) { 'pong' } let(:client_cert) { OpenSSL::X509::Certificate.new fixture_dir.join("client.crt").read } let(:client_key) { OpenSSL::PKey::RSA.new fixture_dir.join("client.key").read } let(:client_context) do OpenSSL::SSL::SSLContext.new.tap do |context| context.cert = client_cert context.key = client_key end end let(:client) do remaining_attempts = 3 begin TCPSocket.new example_addr, example_ssl_port rescue Errno::ECONNREFUSED # HAX: sometimes this fails to connect? o_O # This is quite likely due to the Thread.pass style spinlocks for startup raise if remaining_attempts < 1 remaining_attempts -= 1 # Seems gimpy, but sleep and retry sleep 0.1 retry end end let(:ssl_client) { Celluloid::IO::SSLSocket.new client, client_context } let(:server_cert) { OpenSSL::X509::Certificate.new fixture_dir.join("server.crt").read } let(:server_key) { OpenSSL::PKey::RSA.new fixture_dir.join("server.key").read } let(:server_context) do OpenSSL::SSL::SSLContext.new.tap do |context| context.cert = server_cert context.key = server_key end end let(:server) { TCPServer.new example_addr, example_ssl_port } let(:ssl_server) { OpenSSL::SSL::SSLServer.new server, server_context } let(:server_thread) do Thread.new { ssl_server.accept }.tap do |thread| Thread.pass while thread.status && thread.status != "sleep" thread.join unless thread.status end end let(:celluloid_server) { Celluloid::IO::TCPServer.new example_addr, example_ssl_port } let(:raw_server_thread) do Thread.new { celluloid_server.accept }.tap do |thread| Thread.pass while thread.status && thread.status != "sleep" thread.join unless thread.status end end context "duck typing ::SSLSocket" do it "responds to #peeraddr" do with_ssl_sockets do |ssl_client, ssl_peer| expect{ ssl_client.peeraddr }.to_not raise_error end end end context "inside Celluloid::IO" do it "connects to SSL servers over TCP" do with_ssl_sockets do |ssl_client, ssl_peer| within_io_actor do ssl_peer << request ssl_client.read(request.size).should eq(request) ssl_client << response ssl_peer.read(response.size).should eq(response) end end end it "starts SSL on a connected TCP socket" do pending "JRuby support" if defined?(JRUBY_VERSION) with_raw_sockets do |client, peer| within_io_actor do peer << request client.read(request.size).should eq(request) client << response peer.read(response.size).should eq(response) # now that we've written bytes, upgrade to SSL client_thread = Thread.new { OpenSSL::SSL::SSLSocket.new(client).connect } ssl_peer = Celluloid::IO::SSLSocket.new peer, server_context ssl_peer.should eq(ssl_peer.accept) ssl_client = client_thread.value ssl_peer << request ssl_client.read(request.size).should eq(request) ssl_client << response ssl_peer.read(response.size).should eq(response) end end end end context "outside Celluloid::IO" do it "connects to SSL servers over TCP" do with_ssl_sockets do |ssl_client, ssl_peer| ssl_peer << request ssl_client.read(request.size).should eq(request) ssl_client << response ssl_peer.read(response.size).should eq(response) end end it "starts SSL on a connected TCP socket" do pending "JRuby support" if defined?(JRUBY_VERSION) with_raw_sockets do |client, peer| peer << request client.read(request.size).should eq(request) client << response peer.read(response.size).should eq(response) # now that we've written bytes, upgrade to SSL client_thread = Thread.new { OpenSSL::SSL::SSLSocket.new(client).connect } ssl_peer = Celluloid::IO::SSLSocket.new peer, server_context ssl_peer.should eq(ssl_peer.accept) ssl_client = client_thread.value ssl_peer << request ssl_client.read(request.size).should eq(request) ssl_client << response ssl_peer.read(response.size).should eq(response) end end end it "knows its cert" do # FIXME: seems bad? o_O pending "wtf is wrong with this on JRuby" if defined? JRUBY_VERSION with_ssl_sockets do |ssl_client| ssl_client.cert.to_der.should eq(client_cert.to_der) end end it "knows its peer_cert" do with_ssl_sockets do |ssl_client| ssl_client.peer_cert.to_der.should eq(ssl_client.to_io.peer_cert.to_der) end end it "knows its peer_cert_chain" do with_ssl_sockets do |ssl_client| ssl_client.peer_cert_chain.zip(ssl_client.to_io.peer_cert_chain).map do |c1, c2| c1.to_der == c2.to_der end.should be_all end end it "knows its cipher" do with_ssl_sockets do |ssl_client| ssl_client.cipher.should eq(ssl_client.to_io.cipher) end end it "knows its client_ca" do # jruby-openssl does not implement this method pending "jruby-openssl support" if defined? JRUBY_VERSION with_ssl_sockets do |ssl_client| ssl_client.client_ca.should eq(ssl_client.to_io.client_ca) end end it "verifies peer certificates" do # FIXME: JRuby seems to be giving the wrong result here o_O pending "jruby-openssl support" if defined? JRUBY_VERSION with_ssl_sockets do |ssl_client, ssl_peer| ssl_client.verify_result.should eq(OpenSSL::X509::V_ERR_DEPTH_ZERO_SELF_SIGNED_CERT) end end def with_ssl_sockets server_thread ssl_client.connect begin ssl_peer = server_thread.value yield ssl_client, ssl_peer ensure server_thread.join ssl_server.close ssl_client.close ssl_peer.close end end def with_raw_sockets raw_server_thread client begin peer = raw_server_thread.value yield client, peer ensure raw_server_thread.join celluloid_server.close client.close peer.close end end end celluloid-io-0.16.2/spec/celluloid/io/actor_spec.rb0000644000004100000410000000015212477620141022177 0ustar www-datawww-datarequire 'spec_helper' describe Celluloid::IO do it_behaves_like "a Celluloid Actor", Celluloid::IO end celluloid-io-0.16.2/spec/celluloid/io/udp_socket_spec.rb0000644000004100000410000000155612477620141023240 0ustar www-datawww-datarequire 'spec_helper' describe Celluloid::IO::UDPSocket do let(:payload) { 'ohai' } subject do Celluloid::IO::UDPSocket.new.tap do |sock| sock.bind example_addr, example_port end end after { subject.close } context "inside Celluloid::IO" do it "should be evented" do within_io_actor { Celluloid::IO.evented? }.should be_true end it "sends and receives packets" do within_io_actor do subject.send payload, 0, example_addr, example_port subject.recvfrom(payload.size).first.should == payload end end end context "outside Celluloid::IO" do it "should be blocking" do Celluloid::IO.should_not be_evented end it "sends and receives packets" do subject.send payload, 0, example_addr, example_port subject.recvfrom(payload.size).first.should == payload end end end celluloid-io-0.16.2/spec/celluloid/io/dns_resolver_spec.rb0000644000004100000410000000312112477620141023573 0ustar www-datawww-datarequire 'spec_helper' describe Celluloid::IO::DNSResolver do describe '#resolve' do it 'resolves hostnames statically from hosts file without nameservers' do # /etc/resolv.conf doesn't exist on Mac OSX when no networking is # disabled, thus .nameservers would return nil Celluloid::IO::DNSResolver.should_receive(:nameservers).at_most(:once) { nil } resolver = Celluloid::IO::DNSResolver.new resolver.resolve('localhost').should eq Resolv::IPv4.create("127.0.0.1") end it 'resolves hostnames' do resolver = Celluloid::IO::DNSResolver.new resolver.resolve('localhost').should eq Resolv::IPv4.create("127.0.0.1") end it "resolves domain names" do resolver = Celluloid::IO::DNSResolver.new nameservers = resolver.resolve("celluloid.io") expect(nameservers).to include Resolv::IPv4.create("104.28.21.100") expect(nameservers).to include Resolv::IPv4.create("104.28.20.100") end it "resolves CNAME responses" do resolver = Celluloid::IO::DNSResolver.new results = resolver.resolve("www.google.com") if results.is_a?(Array) results.all? {|i| i.should be_an_instance_of(Resolv::IPv4) } else results.should be_an_instance_of(Resolv::IPv4) end # www.yahoo.com will be resolved randomly whether multiple or # single entry. results = resolver.resolve("www.yahoo.com") if results.is_a?(Array) results.all? {|i| i.should be_an_instance_of(Resolv::IPv4) } else results.should be_an_instance_of(Resolv::IPv4) end end end end celluloid-io-0.16.2/spec/celluloid/io_spec.rb0000644000004100000410000000107612477620141021075 0ustar www-datawww-datarequire 'spec_helper' describe Celluloid::IO do context "copy_stream" do let(:host) { "127.0.0.1" } let(:port) { 23456 } it "copies streams from Celluloid::IO sockets" do server = described_class::TCPServer.new(host, port) client = ::TCPSocket.new(host, port) peer = server.accept expect(peer).to be_a described_class::TCPSocket my_own_bits = File.read(__FILE__) file = File.open(__FILE__, 'r') described_class.copy_stream(file, peer) expect(client.read(file.stat.size)).to eq my_own_bits end end endcelluloid-io-0.16.2/.travis.yml0000644000004100000410000000040012477620141016320 0ustar www-datawww-datascript: rake ci rvm: - 1.9.3 - 2.0.0 - 2.1.1 - ruby-head - jruby - jruby-head - rbx-2 matrix: allow_failures: - rvm: ruby-head - rvm: jruby - rvm: jruby-head - rvm: rbx-2 notifications: irc: "irc.freenode.org#celluloid" celluloid-io-0.16.2/lib/0000755000004100000410000000000012477620141014763 5ustar www-datawww-datacelluloid-io-0.16.2/lib/celluloid/0000755000004100000410000000000012477620141016737 5ustar www-datawww-datacelluloid-io-0.16.2/lib/celluloid/io/0000755000004100000410000000000012477620141017346 5ustar www-datawww-datacelluloid-io-0.16.2/lib/celluloid/io/ssl_socket.rb0000644000004100000410000000161612477620141022050 0ustar www-datawww-datarequire 'openssl' module Celluloid module IO # SSLSocket with Celluloid::IO support class SSLSocket < Stream extend Forwardable def_delegators :@socket, :read_nonblock, :write_nonblock, :close, :closed?, :cert, :cipher, :client_ca, :peer_cert, :peer_cert_chain, :verify_result, :peeraddr def initialize(io, ctx = OpenSSL::SSL::SSLContext.new) super() @context = ctx @socket = OpenSSL::SSL::SSLSocket.new(::IO.try_convert(io), @context) end def connect @socket.connect_nonblock self rescue ::IO::WaitReadable wait_readable retry end def accept @socket.accept_nonblock self rescue ::IO::WaitReadable wait_readable retry rescue ::IO::WaitWritable wait_writable retry end def to_io; @socket; end end end end celluloid-io-0.16.2/lib/celluloid/io/mailbox.rb0000644000004100000410000000033312477620141021325 0ustar www-datawww-datamodule Celluloid module IO # An alternative implementation of Celluloid::Mailbox using Reactor class Mailbox < Celluloid::EventedMailbox def initialize super(Reactor) end end end end celluloid-io-0.16.2/lib/celluloid/io/unix_socket.rb0000644000004100000410000000212512477620141022226 0ustar www-datawww-datarequire 'socket' module Celluloid module IO # UNIXSocket with combined blocking and evented support class UNIXSocket < Stream extend Forwardable def_delegators :@socket, :read_nonblock, :write_nonblock, :close, :closed?, :readline, :puts, :addr # Open a UNIX connection. def self.open(socket_path, &block) self.new(socket_path, &block) end # Convert a Ruby UNIXSocket into a Celluloid::IO::UNIXSocket # DEPRECATED: to be removed in a future release def self.from_ruby_socket(ruby_socket) new(ruby_socket) end # Open a UNIX connection. def initialize(socket_path, &block) super() # Allow users to pass in a Ruby UNIXSocket directly if socket_path.is_a? ::UNIXSocket @socket = socket_path return end # FIXME: not doing non-blocking connect @socket = if block ::UNIXSocket.open(socket_path, &block) else ::UNIXSocket.new(socket_path) end end def to_io @socket end end end end celluloid-io-0.16.2/lib/celluloid/io/ssl_server.rb0000644000004100000410000000152112477620141022061 0ustar www-datawww-datarequire 'socket' module Celluloid module IO # SSLServer wraps a TCPServer to provide immediate SSL accept class SSLServer extend Forwardable def_delegators :@tcp_server, :listen, :shutdown, :close, :closed?, :to_io attr_accessor :start_immediately attr_reader :tcp_server def initialize(server, ctx) if server.is_a?(::TCPServer) server = Celluloid::IO::TCPServer.from_ruby_server(server) end @tcp_server = server @ctx = ctx @start_immediately = true end def accept sock = @tcp_server.accept begin ssl = Celluloid::IO::SSLSocket.new(sock, @ctx) ssl.accept if @start_immediately ssl rescue OpenSSL::SSL::SSLError sock.close raise end end end end end celluloid-io-0.16.2/lib/celluloid/io/tcp_socket.rb0000644000004100000410000000715212477620141022036 0ustar www-datawww-datarequire 'socket' require 'resolv' module Celluloid module IO # TCPSocket with combined blocking and evented support class TCPSocket < Stream extend Forwardable def_delegators :@socket, :read_nonblock, :write_nonblock, :close, :close_read, :close_write, :closed? def_delegators :@socket, :addr, :peeraddr, :setsockopt, :getsockname # Open a TCP socket, yielding it to the given block and closing it # automatically when done (if a block is given) def self.open(*args, &block) sock = new(*args) return sock unless block_given? begin yield(sock) ensure sock.close end end # Convert a Ruby TCPSocket into a Celluloid::IO::TCPSocket # DEPRECATED: to be removed in a future release def self.from_ruby_socket(ruby_socket) new(ruby_socket) end # Opens a TCP connection to remote_host on remote_port. If local_host # and local_port are specified, then those parameters are used on the # local end to establish the connection. def initialize(remote_host, remote_port = nil, local_host = nil, local_port = nil) super() # Allow users to pass in a Ruby TCPSocket directly if remote_host.is_a? ::TCPSocket @addr = nil @socket = remote_host return elsif remote_port.nil? raise ArgumentError, "wrong number of arguments (1 for 2)" end # Is it an IPv4 address? begin @addr = Resolv::IPv4.create(remote_host) rescue ArgumentError end # Guess it's not IPv4! Is it IPv6? unless @addr begin @addr = Resolv::IPv6.create(remote_host) rescue ArgumentError end end # Guess it's not an IP address, so let's try DNS unless @addr addrs = Array(DNSResolver.new.resolve(remote_host)) raise Resolv::ResolvError, "DNS result has no information for #{remote_host}" if addrs.empty? # Pseudorandom round-robin DNS support :/ @addr = addrs[rand(addrs.size)] end case @addr when Resolv::IPv4 family = Socket::AF_INET when Resolv::IPv6 family = Socket::AF_INET6 else raise ArgumentError, "unsupported address class: #{@addr.class}" end @socket = Socket.new(family, Socket::SOCK_STREAM, 0) @socket.bind Addrinfo.tcp(local_host, local_port) if local_host begin @socket.connect_nonblock Socket.sockaddr_in(remote_port, @addr.to_s) rescue Errno::EINPROGRESS wait_writable # HAX: for some reason we need to finish_connect ourselves on JRuby # This logic is unnecessary but JRuby still throws Errno::EINPROGRESS # if we retry the non-blocking connect instead of just finishing it retry unless defined?(JRUBY_VERSION) && @socket.to_channel.finish_connect rescue Errno::EISCONN # We're now connected! Yay exceptions for flow control # NOTE: This is the approach the Ruby stdlib docs suggest ;_; end end def to_io @socket end # Receives a message def recv(maxlen, flags = nil) raise NotImplementedError, "flags not supported" if flags && !flags.zero? readpartial(maxlen) end # Send a message def send(msg, flags, dest_sockaddr = nil) raise NotImplementedError, "dest_sockaddr not supported" if dest_sockaddr raise NotImplementedError, "flags not supported" unless flags.zero? write(msg) end end end end celluloid-io-0.16.2/lib/celluloid/io/dns_resolver.rb0000644000004100000410000000503412477620141022402 0ustar www-datawww-datarequire 'ipaddr' require 'resolv' module Celluloid module IO # Asynchronous DNS resolver using Celluloid::IO::UDPSocket class DNSResolver # Maximum UDP packet we'll accept MAX_PACKET_SIZE = 512 DNS_PORT = 53 @mutex = Mutex.new @identifier = 1 def self.generate_id @mutex.synchronize { @identifier = (@identifier + 1) & 0xFFFF } end def self.nameservers Resolv::DNS::Config.default_config_hash[:nameserver] end def initialize # early return for edge case when there are no nameservers configured # but we still want to be able to static lookups using #resolve_hostname @nameservers = self.class.nameservers or return @server = IPAddr.new(@nameservers.sample) # The non-blocking secret sauce is here, as this is actually a # Celluloid::IO::UDPSocket @socket = UDPSocket.new(@server.family) end def resolve(hostname) if host = resolve_hostname(hostname) unless ip_address = resolve_host(host) raise Resolv::ResolvError, "invalid entry in hosts file: #{host}" end return ip_address end query = build_query(hostname) @socket.send query.encode, 0, @server.to_s, DNS_PORT data, _ = @socket.recvfrom(MAX_PACKET_SIZE) response = Resolv::DNS::Message.decode(data) addrs = [] # The answer might include IN::CNAME entries so filters them out # to include IN::A & IN::AAAA entries only. response.each_answer { |name, ttl, value| addrs << value.address if value.respond_to?(:address) } return if addrs.empty? return addrs.first if addrs.size == 1 addrs end private def resolve_hostname(hostname) # Resolv::Hosts#getaddresses pushes onto a stack # so since we want the first occurance, simply # pop off the stack. resolv.getaddresses(hostname).pop rescue nil end def resolv @resolv ||= Resolv::Hosts.new end def build_query(hostname) Resolv::DNS::Message.new.tap do |query| query.id = self.class.generate_id query.rd = 1 query.add_question hostname, Resolv::DNS::Resource::IN::A end end def resolve_host(host) resolve_ip(Resolv::IPv4, host) || resolve_ip(Resolv::IPv6, host) end def resolve_ip(klass, host) begin klass.create(host) rescue ArgumentError end end end end end celluloid-io-0.16.2/lib/celluloid/io/version.rb0000644000004100000410000000007612477620141021363 0ustar www-datawww-datamodule Celluloid module IO VERSION = "0.16.2" end end celluloid-io-0.16.2/lib/celluloid/io/udp_socket.rb0000644000004100000410000000217412477620141022037 0ustar www-datawww-datamodule Celluloid module IO # UDPSockets with combined blocking and evented support class UDPSocket extend Forwardable def_delegators :@socket, :addr, :bind, :connect, :send, :recvfrom_nonblock, :close, :closed? def initialize(address_family = ::Socket::AF_INET) @socket = ::UDPSocket.new(address_family) end # Wait until the socket is readable def wait_readable; Celluloid::IO.wait_readable(self); end # Receives up to maxlen bytes from socket. flags is zero or more of the # MSG_ options. The first element of the results, mesg, is the data # received. The second element, sender_addrinfo, contains # protocol-specific address information of the sender. def recvfrom(maxlen, flags = nil) begin if @socket.respond_to? :recvfrom_nonblock @socket.recvfrom_nonblock(maxlen, flags) else # FIXME: hax for JRuby @socket.recvfrom(maxlen, flags) end rescue ::IO::WaitReadable wait_readable retry end end def to_io; @socket; end end end end celluloid-io-0.16.2/lib/celluloid/io/tcp_server.rb0000644000004100000410000000165512477620141022056 0ustar www-datawww-datarequire 'socket' module Celluloid module IO # TCPServer with combined blocking and evented support class TCPServer extend Forwardable def_delegators :@server, :listen, :sysaccept, :close, :closed?, :addr, :setsockopt def initialize(hostname_or_port, port = nil) if port.nil? @server = ::TCPServer.new(hostname_or_port) else @server = ::TCPServer.new(hostname_or_port, port) end end def accept Celluloid::IO.wait_readable(@server) accept_nonblock end def accept_nonblock Celluloid::IO::TCPSocket.new(@server.accept_nonblock) end def to_io @server end # Convert a Ruby TCPServer into a Celluloid::IO::TCPServer def self.from_ruby_server(ruby_server) server = allocate server.instance_variable_set(:@server, ruby_server) server end end end end celluloid-io-0.16.2/lib/celluloid/io/unix_server.rb0000644000004100000410000000120712477620141022244 0ustar www-datawww-datarequire 'socket' module Celluloid module IO # UNIXServer with combined blocking and evented support class UNIXServer extend Forwardable def_delegators :@server, :listen, :sysaccept, :close, :closed? def self.open(socket_path) self.new(socket_path) end def initialize(socket_path) @server = ::UNIXServer.new(socket_path) end def accept Celluloid::IO.wait_readable(@server) accept_nonblock end def accept_nonblock Celluloid::IO::UNIXSocket.new(@server.accept_nonblock) end def to_io @server end end end end celluloid-io-0.16.2/lib/celluloid/io/reactor.rb0000644000004100000410000000363412477620141021340 0ustar www-datawww-datarequire 'nio' module Celluloid module IO # React to external I/O events. This is kinda sorta supposed to resemble the # Reactor design pattern. class Reactor extend Forwardable # Unblock the reactor (i.e. to signal it from another thread) def_delegator :@selector, :wakeup # Terminate the reactor def_delegator :@selector, :close, :shutdown def initialize @selector = NIO::Selector.new end # Wait for the given IO object to become readable def wait_readable(io) wait io, :r end # Wait for the given IO object to become writable def wait_writable(io) wait io, :w end # Wait for the given IO operation to complete def wait(io, set) # zomg ugly type conversion :( unless io.is_a?(::IO) or io.is_a?(OpenSSL::SSL::SSLSocket) if io.respond_to? :to_io io = io.to_io elsif ::IO.respond_to? :try_convert io = ::IO.try_convert(io) end raise TypeError, "can't convert #{io.class} into IO" unless io.is_a?(::IO) end monitor = @selector.register(io, set) monitor.value = Task.current begin Task.suspend :iowait ensure # In all cases we want to ensure that the monitor is closed once we # have woken up. However, in some cases, the monitor is already # invalid, e.g. in the case that we are terminating. We catch this # case explicitly. monitor.close end end # Run the reactor, waiting for events or wakeup signal def run_once(timeout = nil) @selector.select(timeout) do |monitor| task = monitor.value if task.running? task.resume else Logger.warn("reactor attempted to resume a dead task") end end end end end end celluloid-io-0.16.2/lib/celluloid/io/stream.rb0000644000004100000410000002300612477620141021167 0ustar www-datawww-data# Partially adapted from Ruby's OpenSSL::Buffering # Originally from the 'OpenSSL for Ruby 2' project # Copyright (C) 2001 GOTOU YUUZOU # All rights reserved. # # This program is licenced under the same licence as Ruby. module Celluloid module IO # Base class of all streams in Celluloid::IO class Stream include Enumerable # The "sync mode" of the stream # # See IO#sync for full details. attr_accessor :sync def initialize @eof = false @sync = true @read_buffer = ''.force_encoding(Encoding::ASCII_8BIT) @write_buffer = ''.force_encoding(Encoding::ASCII_8BIT) @read_latch = Latch.new @write_latch = Latch.new end # Wait until the current object is readable def wait_readable; Celluloid::IO.wait_readable(self); end # Wait until the current object is writable def wait_writable; Celluloid::IO.wait_writable(self); end # System read via the nonblocking subsystem def sysread(length = nil, buffer = nil) buffer ||= ''.force_encoding(Encoding::ASCII_8BIT) @read_latch.synchronize do begin read_nonblock(length, buffer) rescue ::IO::WaitReadable wait_readable retry end end buffer end # System write via the nonblocking subsystem def syswrite(string) length = string.length total_written = 0 remaining = string @write_latch.synchronize do while total_written < length begin written = write_nonblock(remaining) rescue ::IO::WaitWritable wait_writable retry rescue EOFError return total_written rescue Errno::EAGAIN wait_writable retry end total_written += written # FIXME: mutating the original buffer here. Seems bad. remaining.slice!(0, written) if written < remaining.length end end total_written end # Reads +size+ bytes from the stream. If +buf+ is provided it must # reference a string which will receive the data. # # See IO#read for full details. def read(size=nil, buf=nil) if size == 0 if buf buf.clear return buf else return "" end end until @eof break if size && size <= @read_buffer.size fill_rbuff break unless size end ret = consume_rbuff(size) || "" if buf buf.replace(ret) ret = buf end (size && ret.empty?) ? nil : ret end # Reads at most +maxlen+ bytes from the stream. If +buf+ is provided it # must reference a string which will receive the data. # # See IO#readpartial for full details. def readpartial(maxlen, buf=nil) if maxlen == 0 if buf buf.clear return buf else return "" end end if @read_buffer.empty? begin return sysread(maxlen, buf) rescue Errno::EAGAIN retry end end ret = consume_rbuff(maxlen) if buf buf.replace(ret) ret = buf end raise EOFError if ret.empty? ret end # Reads the next "line+ from the stream. Lines are separated by +eol+. If # +limit+ is provided the result will not be longer than the given number of # bytes. # # +eol+ may be a String or Regexp. # # Unlike IO#gets the line read will not be assigned to +$_+. # # Unlike IO#gets the separator must be provided if a limit is provided. def gets(eol=$/, limit=nil) idx = @read_buffer.index(eol) until @eof break if idx fill_rbuff idx = @read_buffer.index(eol) end if eol.is_a?(Regexp) size = idx ? idx+$&.size : nil else size = idx ? idx+eol.size : nil end if limit and limit >= 0 size = [size, limit].min end consume_rbuff(size) end # Executes the block for every line in the stream where lines are separated # by +eol+. # # See also #gets def each(eol=$/) while line = self.gets(eol) yield line end end alias each_line each # Reads lines from the stream which are separated by +eol+. # # See also #gets def readlines(eol=$/) ary = [] while line = self.gets(eol) ary << line end ary end # Reads a line from the stream which is separated by +eol+. # # Raises EOFError if at end of file. def readline(eol=$/) raise EOFError if eof? gets(eol) end # Reads one character from the stream. Returns nil if called at end of # file. def getc read(1) end # Calls the given block once for each byte in the stream. def each_byte # :yields: byte while c = getc yield(c.ord) end end # Reads a one-character string from the stream. Raises an EOFError at end # of file. def readchar raise EOFError if eof? getc end # Pushes character +c+ back onto the stream such that a subsequent buffered # character read will return it. # # Unlike IO#getc multiple bytes may be pushed back onto the stream. # # Has no effect on unbuffered reads (such as #sysread). def ungetc(c) @read_buffer[0,0] = c.chr end # Returns true if the stream is at file which means there is no more data to # be read. def eof? fill_rbuff if !@eof && @read_buffer.empty? @eof && @read_buffer.empty? end alias eof eof? # Writes +s+ to the stream. If the argument is not a string it will be # converted using String#to_s. Returns the number of bytes written. def write(s) do_write(s) s.bytesize end # Writes +s+ to the stream. +s+ will be converted to a String using # String#to_s. def << (s) do_write(s) self end # Writes +args+ to the stream along with a record separator. # # See IO#puts for full details. def puts(*args) s = "" if args.empty? s << "\n" end args.each do |arg| s << arg.to_s if $/ && /\n\z/ !~ s s << "\n" end end do_write(s) nil end # Writes +args+ to the stream. # # See IO#print for full details. def print(*args) s = "" args.each { |arg| s << arg.to_s } do_write(s) nil end # Formats and writes to the stream converting parameters under control of # the format string. # # See Kernel#sprintf for format string details. def printf(s, *args) do_write(s % args) nil end # Flushes buffered data to the stream. def flush osync = @sync @sync = true do_write "" return self ensure @sync = osync end # Closes the stream and flushes any unwritten data. def close flush rescue nil sysclose end ####### private ####### # Fills the buffer from the underlying stream def fill_rbuff begin @read_buffer << sysread(BLOCK_SIZE) rescue Errno::EAGAIN retry rescue EOFError @eof = true end end # Consumes +size+ bytes from the buffer def consume_rbuff(size=nil) if @read_buffer.empty? nil else size = @read_buffer.size unless size ret = @read_buffer[0, size] @read_buffer[0, size] = "" ret end end # Writes +s+ to the buffer. When the buffer is full or #sync is true the # buffer is flushed to the underlying stream. def do_write(s) @write_buffer << s @write_buffer.force_encoding(Encoding::BINARY) if @sync or @write_buffer.size > BLOCK_SIZE or idx = @write_buffer.rindex($/) remain = idx ? idx + $/.size : @write_buffer.length nwritten = 0 while remain > 0 str = @write_buffer[nwritten,remain] begin nwrote = syswrite(str) rescue Errno::EAGAIN retry end remain -= nwrote nwritten += nwrote end @write_buffer[0,nwritten] = "" end end # Perform an operation exclusively, uncontested by other tasks class Latch def initialize @owner = nil @waiters = 0 @condition = Celluloid::Condition.new end # Synchronize an operation across all tasks in the current actor def synchronize actor = Thread.current[:celluloid_actor] return yield unless actor if @owner || @waiters > 0 @waiters += 1 @condition.wait @waiters -= 1 end @owner = Task.current begin ret = yield ensure @owner = nil @condition.signal if @waiters > 0 end ret end end end end end celluloid-io-0.16.2/lib/celluloid/io.rb0000644000004100000410000000346112477620141017677 0ustar www-datawww-datarequire 'celluloid/io/version' require 'celluloid' require 'celluloid/io/dns_resolver' require 'celluloid/io/mailbox' require 'celluloid/io/reactor' require 'celluloid/io/stream' require 'celluloid/io/tcp_server' require 'celluloid/io/tcp_socket' require 'celluloid/io/udp_socket' require 'celluloid/io/unix_server' require 'celluloid/io/unix_socket' require 'celluloid/io/ssl_server' require 'celluloid/io/ssl_socket' module Celluloid # Actors with evented IO support module IO # Default size to read from or write to the stream for buffer operations BLOCK_SIZE = 1024 * 16 def self.included(klass) klass.send :include, Celluloid klass.mailbox_class Celluloid::IO::Mailbox end def self.evented? actor = Thread.current[:celluloid_actor] actor && actor.mailbox.is_a?(Celluloid::IO::Mailbox) end def self.try_convert(src) ::IO.try_convert(src) end def self.copy_stream(src, dst, copy_length = nil, src_offset = nil) raise NotImplementedError, "length/offset not supported" if copy_length || src_offset src, dst = try_convert(src), try_convert(dst) # FIXME: this always goes through the reactor, and can block on file I/O while data = src.read(BLOCK_SIZE) dst << data end end def wait_readable(io) io = io.to_io if IO.evented? mailbox = Thread.current[:celluloid_mailbox] mailbox.reactor.wait_readable(io) else Kernel.select([io]) end nil end module_function :wait_readable def wait_writable(io) io = io.to_io if IO.evented? mailbox = Thread.current[:celluloid_mailbox] mailbox.reactor.wait_writable(io) else Kernel.select([], [io]) end nil end module_function :wait_writable end end celluloid-io-0.16.2/metadata.yml0000644000004100000410000001251612477620141016525 0ustar www-datawww-data--- !ruby/object:Gem::Specification name: celluloid-io version: !ruby/object:Gem::Version version: 0.16.2 platform: ruby authors: - Tony Arcieri autorequire: bindir: bin cert_chain: [] date: 2015-01-30 00:00:00.000000000 Z dependencies: - !ruby/object:Gem::Dependency name: celluloid requirement: !ruby/object:Gem::Requirement requirements: - - ">=" - !ruby/object:Gem::Version version: 0.16.0 type: :runtime prerelease: false version_requirements: !ruby/object:Gem::Requirement requirements: - - ">=" - !ruby/object:Gem::Version version: 0.16.0 - !ruby/object:Gem::Dependency name: nio4r requirement: !ruby/object:Gem::Requirement requirements: - - ">=" - !ruby/object:Gem::Version version: 1.1.0 type: :runtime prerelease: false version_requirements: !ruby/object:Gem::Requirement requirements: - - ">=" - !ruby/object:Gem::Version version: 1.1.0 - !ruby/object:Gem::Dependency name: rake requirement: !ruby/object:Gem::Requirement requirements: - - ">=" - !ruby/object:Gem::Version version: '0' type: :development prerelease: false version_requirements: !ruby/object:Gem::Requirement requirements: - - ">=" - !ruby/object:Gem::Version version: '0' - !ruby/object:Gem::Dependency name: rspec requirement: !ruby/object:Gem::Requirement requirements: - - "~>" - !ruby/object:Gem::Version version: 2.14.0 type: :development prerelease: false version_requirements: !ruby/object:Gem::Requirement requirements: - - "~>" - !ruby/object:Gem::Version version: 2.14.0 - !ruby/object:Gem::Dependency name: benchmark_suite requirement: !ruby/object:Gem::Requirement requirements: - - ">=" - !ruby/object:Gem::Version version: '0' type: :development prerelease: false version_requirements: !ruby/object:Gem::Requirement requirements: - - ">=" - !ruby/object:Gem::Version version: '0' - !ruby/object:Gem::Dependency name: guard-rspec requirement: !ruby/object:Gem::Requirement requirements: - - ">=" - !ruby/object:Gem::Version version: '0' type: :development prerelease: false version_requirements: !ruby/object:Gem::Requirement requirements: - - ">=" - !ruby/object:Gem::Version version: '0' - !ruby/object:Gem::Dependency name: rb-fsevent requirement: !ruby/object:Gem::Requirement requirements: - - "~>" - !ruby/object:Gem::Version version: 0.9.1 type: :development prerelease: false version_requirements: !ruby/object:Gem::Requirement requirements: - - "~>" - !ruby/object:Gem::Version version: 0.9.1 description: Evented IO for Celluloid actors email: - tony.arcieri@gmail.com executables: [] extensions: [] extra_rdoc_files: [] files: - ".coveralls.yml" - ".gitignore" - ".rspec" - ".travis.yml" - CHANGES.md - Gemfile - Guardfile - LICENSE.txt - README.md - Rakefile - benchmarks/actor.rb - celluloid-io.gemspec - examples/echo_client.rb - examples/echo_server.rb - examples/echo_unix_client.rb - examples/echo_unix_server.rb - lib/celluloid/io.rb - lib/celluloid/io/dns_resolver.rb - lib/celluloid/io/mailbox.rb - lib/celluloid/io/reactor.rb - lib/celluloid/io/ssl_server.rb - lib/celluloid/io/ssl_socket.rb - lib/celluloid/io/stream.rb - lib/celluloid/io/tcp_server.rb - lib/celluloid/io/tcp_socket.rb - lib/celluloid/io/udp_socket.rb - lib/celluloid/io/unix_server.rb - lib/celluloid/io/unix_socket.rb - lib/celluloid/io/version.rb - log/.gitignore - logo.png - spec/celluloid/io/actor_spec.rb - spec/celluloid/io/dns_resolver_spec.rb - spec/celluloid/io/mailbox_spec.rb - spec/celluloid/io/reactor_spec.rb - spec/celluloid/io/ssl_server_spec.rb - spec/celluloid/io/ssl_socket_spec.rb - spec/celluloid/io/tcp_server_spec.rb - spec/celluloid/io/tcp_socket_spec.rb - spec/celluloid/io/udp_socket_spec.rb - spec/celluloid/io/unix_server_spec.rb - spec/celluloid/io/unix_socket_spec.rb - spec/celluloid/io_spec.rb - spec/fixtures/client.crt - spec/fixtures/client.key - spec/fixtures/server.crt - spec/fixtures/server.key - spec/spec_helper.rb - tasks/benchmarks.task - tasks/rspec.task homepage: http://github.com/celluloid/celluloid-io licenses: - MIT metadata: {} post_install_message: rdoc_options: [] require_paths: - lib required_ruby_version: !ruby/object:Gem::Requirement requirements: - - ">=" - !ruby/object:Gem::Version version: '0' required_rubygems_version: !ruby/object:Gem::Requirement requirements: - - ">=" - !ruby/object:Gem::Version version: '0' requirements: [] rubyforge_project: rubygems_version: 2.4.5 signing_key: specification_version: 4 summary: Celluloid::IO allows you to monitor multiple IO objects within a Celluloid actor test_files: - spec/celluloid/io/actor_spec.rb - spec/celluloid/io/dns_resolver_spec.rb - spec/celluloid/io/mailbox_spec.rb - spec/celluloid/io/reactor_spec.rb - spec/celluloid/io/ssl_server_spec.rb - spec/celluloid/io/ssl_socket_spec.rb - spec/celluloid/io/tcp_server_spec.rb - spec/celluloid/io/tcp_socket_spec.rb - spec/celluloid/io/udp_socket_spec.rb - spec/celluloid/io/unix_server_spec.rb - spec/celluloid/io/unix_socket_spec.rb - spec/celluloid/io_spec.rb - spec/fixtures/client.crt - spec/fixtures/client.key - spec/fixtures/server.crt - spec/fixtures/server.key - spec/spec_helper.rb celluloid-io-0.16.2/.gitignore0000644000004100000410000000023212477620141016202 0ustar www-datawww-data*.gem *.rbc .bundle .config .yardoc Gemfile.lock InstalledFiles _yardoc coverage doc/ lib/bundler/man pkg rdoc spec/reports test/tmp test/version_tmp tmp celluloid-io-0.16.2/celluloid-io.gemspec0000644000004100000410000000221612477620141020144 0ustar www-datawww-data# -*- encoding: utf-8 -*- require File.expand_path('../lib/celluloid/io/version', __FILE__) Gem::Specification.new do |gem| gem.name = "celluloid-io" gem.version = Celluloid::IO::VERSION gem.license = 'MIT' gem.authors = ["Tony Arcieri"] gem.email = ["tony.arcieri@gmail.com"] gem.description = "Evented IO for Celluloid actors" gem.summary = "Celluloid::IO allows you to monitor multiple IO objects within a Celluloid actor" gem.homepage = "http://github.com/celluloid/celluloid-io" gem.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) } gem.files = `git ls-files`.split("\n") gem.test_files = `git ls-files -- {test,spec,features}/*`.split("\n") gem.require_paths = ["lib"] gem.add_dependency 'celluloid', '>= 0.16.0' gem.add_dependency 'nio4r', '>= 1.1.0' gem.add_development_dependency 'rake' gem.add_development_dependency 'rspec', '~> 2.14.0' gem.add_development_dependency 'benchmark_suite' gem.add_development_dependency 'guard-rspec' gem.add_development_dependency 'rb-fsevent', '~> 0.9.1' if RUBY_PLATFORM =~ /darwin/ end celluloid-io-0.16.2/tasks/0000755000004100000410000000000012477620141015342 5ustar www-datawww-datacelluloid-io-0.16.2/tasks/benchmarks.task0000644000004100000410000000110512477620141020340 0ustar www-datawww-datarequire 'timeout' desc "Run Celluloid benchmarks" task :benchmark do # Travis has an out-of-date version of rbx that rashes on the benchmarks exit 0 if ENV['CI'] and RUBY_ENGINE == 'rbx' begin Timeout.timeout(120) do glob = File.expand_path("../../benchmarks/*.rb", __FILE__) Dir[glob].each { |benchmark| load benchmark } end rescue Exception, Timeout::Error => ex puts "ERROR: Couldn't complete benchmark: #{ex.class}: #{ex}" puts " #{ex.backtrace.join("\n ")}" exit 1 unless ENV['CI'] # Hax for running benchmarks on Travis end end celluloid-io-0.16.2/tasks/rspec.task0000644000004100000410000000017412477620141017344 0ustar www-datawww-datarequire 'rspec/core/rake_task' RSpec::Core::RakeTask.new RSpec::Core::RakeTask.new(:rcov) do |task| task.rcov = true endcelluloid-io-0.16.2/benchmarks/0000755000004100000410000000000012477620141016332 5ustar www-datawww-datacelluloid-io-0.16.2/benchmarks/actor.rb0000755000004100000410000000211412477620141017770 0ustar www-datawww-data#!/usr/bin/env ruby require 'rubygems' require 'bundler/setup' require 'celluloid/io' require 'benchmark/ips' class ExampleActor include Celluloid::IO def initialize @condition = Celluloid::Condition.new end def example_method; end def finished @condition.signal end def wait_until_finished @condition.wait end end example_actor = ExampleActor.new mailbox = Celluloid::IO::Mailbox.new latch_in, latch_out = Queue.new, Queue.new latch = Thread.new do while true n = latch_in.pop for i in 0...n; mailbox.receive; end latch_out << :done end end Benchmark.ips do |ips| ips.report("spawn") { ExampleActor.new.terminate } ips.report("calls") { example_actor.example_method } ips.report("async calls") do |n| waiter = example_actor.future.wait_until_finished for i in 1..n; example_actor.async.example_method; end example_actor.async.finished waiter.value end # Deadlocking o_O =begin ips.report("messages") do |n| latch_in << n for i in 0...n; mailbox << :message; end latch_out.pop end =end end celluloid-io-0.16.2/CHANGES.md0000644000004100000410000000401512477620141015607 0ustar www-datawww-data0.16.2 (2014-01-30) ------------------- * More TCPSocket compatibility fixes * Ensure monitors are closed when tasks resume * Fix Errno::EAGAIN handling in Stream#syswrite 0.16.1 (2014-10-08) ------------------- * Revert read/write interest patch as it caused file descriptor leaks 0.16.0 (2014-09-04) ------------------- * Fix bug handling simultaneous read/write interests * Use Resolv::DNS::Config to obtain nameservers * Celluloid::IO.copy_stream support (uses a background thread) 0.15.0 (2013-09-04) ------------------- * Improved DNS resolver with less NIH and more Ruby stdlib goodness * Better match Ruby stdlib TCPServer API * Add missing #send and #recv on Celluloid::IO::TCPSocket * Add missing #setsockopt method on Celluloid::IO::TCPServer * Add missing #peeraddr method on Celluloid::IO::SSLSocket 0.14.0 (2013-05-07) ------------------- * Add `close_read`/`close_write` delegates for rack-hijack support * Depend on EventedMailbox from core 0.13.1 ------ * Remove overhead for `wait_readable`/`wait_writable` 0.13.0 ------ * Support for many, many more IO methods, particularly line-oriented methods like #gets, #readline, and #readlines * Initial SSL support via Celluloid::IO::SSLSocket and Celluloid::IO::SSLServer * Concurrent writes between tasks of the same actor are now coordinated using Celluloid::Conditions instead of signals * Celluloid 0.13 compatibility fixes 0.12.0 ------ * Tracking release for Celluloid 0.12.0 0.11.0 ------ * "Unofficial" SSL support (via nio4r 0.4.0) 0.10.0 ------ * Read/write operations are now atomic across tasks * True non-blocking connect support * Non-blocking DNS resolution support 0.9.0 ----- * TCPServer, TCPSocket, and UDPSocket classes in Celluloid::IO namespace with both evented and blocking I/O support * Celluloid::IO::Mailbox.new now takes a single parameter to specify an alternative reactor (e.g. Celluloid::ZMQ::Reactor) 0.8.0 ----- * Switch to nio4r-based reactor * Compatibility with Celluloid 0.8.0 API changes 0.7.0 ----- * Initial release forked from Celluloid celluloid-io-0.16.2/README.md0000644000004100000410000000764012477620141015503 0ustar www-datawww-data![Celluloid::IO](https://github.com/celluloid/celluloid-io/raw/master/logo.png) ================ [![Gem Version](https://badge.fury.io/rb/celluloid-io.png)](http://rubygems.org/gems/celluloid-io) [![Build Status](https://secure.travis-ci.org/celluloid/celluloid-io.png?branch=master)](http://travis-ci.org/celluloid/celluloid-io) [![Code Climate](https://codeclimate.com/github/celluloid/celluloid-io.png)](https://codeclimate.com/github/celluloid/celluloid-io) [![Coverage Status](https://coveralls.io/repos/celluloid/celluloid-io/badge.png?branch=master)](https://coveralls.io/r/celluloid/celluloid-io) You don't have to choose between threaded and evented IO! Celluloid::IO provides an event-driven IO system for building fast, scalable network applications that integrates directly with the [Celluloid actor library](https://github.com/celluloid/celluloid), making it easy to combine both threaded and evented concepts. Celluloid::IO is ideal for servers which handle large numbers of mostly-idle connections, such as Websocket servers or chat/messaging systems. Celluloid::IO provides a different class of actor: one that's slightly slower and heavier than standard Celluloid actors, but one which contains a high-performance reactor just like EventMachine or Cool.io. This means Celluloid::IO actors have the power of both Celluloid actors and evented I/O loops. Unlike certain other evented I/O systems which limit you to a single event loop per process, Celluloid::IO lets you make as many actors as you want, system resources permitting. Rather than callbacks, Celluloid::IO exposes a synchronous API built on duck types of Ruby's own IO classes, such as TCPServer and TCPSocket. These classes work identically to their core Ruby counterparts, but in the scope of Celluloid::IO actors provide "evented" performance. Since they're drop-in replacements for the standard classes, there's no need to rewrite every library just to take advantage of Celluloid::IO's event loop and you can freely switch between evented and blocking IO even over the lifetime of a single connection. Celluloid::IO uses the [nio4r gem](https://github.com/celluloid/nio4r) to monitor IO objects, which provides cross-platform and cross-Ruby implementation access to high-performance system calls such as epoll and kqueue. Like Celluloid::IO? [Join the Celluloid Google Group](http://groups.google.com/group/celluloid-ruby) Documentation ------------- [Please see the Celluloid::IO Wiki](https://github.com/celluloid/celluloid-io/wiki) for more detailed documentation and usage notes. [YARD documentation](http://rubydoc.info/github/celluloid/celluloid-io/frames) is also available Installation ------------ Add this line to your application's Gemfile: gem 'celluloid-io' And then execute: $ bundle Or install it yourself as: $ gem install celluloid-io Inside of your Ruby program, require Celluloid::IO with: require 'celluloid/io' Supported Platforms ------------------- Celluloid::IO works on Ruby 1.9.3, 2.0.0, JRuby 1.6+, and Rubinius 2.0. JRuby or Rubinius are the preferred platforms as they support true thread-level parallelism when executing Ruby code, whereas MRI/YARV is constrained by a global interpreter lock (GIL) and can only execute one thread at a time. Celluloid::IO requires Ruby 1.9 mode on all interpreters. Contributing to Celluloid::IO ----------------------------- * Fork this repository on github * Make your changes and send me a pull request * If I like them I'll merge them * If I've accepted a patch, feel free to ask for a commit bit! License ------- Copyright (c) 2013 Tony Arcieri. Distributed under the MIT License. See LICENSE.txt for further details. Contains code originally from the RubySpec project also under the MIT License. Copyright (c) 2008 Engine Yard, Inc. All rights reserved. Contains code originally from the 'OpenSSL for Ruby 2' project released under the Ruby license. Copyright (C) 2001 GOTOU YUUZOU. All rights reserved. celluloid-io-0.16.2/Guardfile0000644000004100000410000000030212477620141016035 0ustar www-datawww-dataguard 'rspec', :cli => '--format documentation' do watch(%r{^spec/.+_spec\.rb$}) watch(%r{^lib/(.+)\.rb$}) { |m| "spec/#{m[1]}_spec.rb" } watch('spec/spec_helper.rb') { "spec/" } end