j fR@sdZddlZddlZddlZddlZddlZddlZddlmZm Z m Z m Z m Z m Z mZmZmZmZmZmZmZee e eeeefZyeWnek riZYnXddZGdddeZeeefZdd Zd d Z d d Z!ddZ"ddddZ#ddddZ$e$Z%ddddddZ&GdddZ'Gddde'Z(ddZ)dddd Z*ej+d!krddl,Z,Gd"d#d#Z-Gd$d%d%e'Z.ndS)&aBasic infrastructure for asynchronous socket service clients and servers. There are only two ways to have a program on a single processor do "more than one thing at a time". Multi-threaded programming is the simplest and most popular way to do it, but there is another very different technique, that lets you have nearly all the advantages of multi-threading, without actually using multiple threads. it's really only practical if your program is largely I/O bound. If your program is CPU bound, then pre-emptive scheduled threads are probably what you really need. Network servers are rarely CPU-bound, however. If your operating system supports the select() system call in its I/O library (and nearly all do), then you can use it to juggle multiple communication channels at once; doing other work while your I/O is taking place in the "background." Although this strategy can seem strange and complex, especially at first, it is in many ways easier to understand and control than multi-threaded programming. The module documented here solves many of the difficult problems for you, making the task of building sophisticated high-performance network servers and clients a snap. N) EALREADY EINPROGRESS EWOULDBLOCK ECONNRESETEINVALENOTCONN ESHUTDOWNEISCONNEBADF ECONNABORTEDEPIPEEAGAIN errorcodec CsOytj|SWn7tttfk rJ|tkr>t|Sd|SYnXdS)NzUnknown error %s)osstrerror ValueError OverflowError NameErrorr)errr-/opt/alt/python34/lib64/python3.4/asyncore.py _strerrorDs  rc@seZdZdS)ExitNowN)__name__ __module__ __qualname__rrrrrLs rc Cs;y|jWn&tk r%Yn|jYnXdS)N)handle_read_event_reraised_exceptions handle_error)objrrrreadQs  r c Cs;y|jWn&tk r%Yn|jYnXdS)N)handle_write_eventrr)rrrrwriteYs  r"c Cs;y|jWn&tk r%Yn|jYnXdS)N)handle_expt_eventrr)rrrr _exceptionas  r$cCsyz|tj@r|jn|tj@r7|jn|tj@rQ|jn|tjtjBtj B@ry|j nWntt k r}z/|j dt kr|jn |j WYdd}~Xn&tk rYn|jYnXdS)Nr)selectPOLLINrPOLLOUTr!POLLPRIr#ZPOLLHUPZPOLLERRZPOLLNVAL handle_closeOSErrorargs _DISCONNECTEDrr)rflagserrr readwriteis"        r/gc Cs|dkrt}n|rg}g}g}xt|jD]v\}}|j}|j}|rz|j|n|r|j r|j|n|s|r@|j|q@q@Wg|ko|ko|knrtj|dSy%t j ||||\}}}Wnt k r/dSYnXx9|D]1}|j |}|dkr^q7nt |q7Wx9|D]1}|j |}|dkrqsnt |qsWx<|D]1}|j |}|dkrqnt|qWndS)N) socket_maplistitemsreadablewritableappend acceptingtimeZsleepr%InterruptedErrorgetr r"r$) timeoutmaprwr.fdrZis_rZis_wrrrpoll}sJ     ' %        r?c CsK|dkrt}n|dk r4t|d}ntj}|rGxt|jD]t\}}d}|jr|tjtjBO}n|j r|j r|tj O}n|rY|j ||qYqYWy|j|}Wnt k rg}YnXxE|D]:\}}|j|}|dkr3qnt||qWndS)Nir)r0intr%r?r1r2r3r&r(r4r6r'registerr8r9r/)r:r;Zpollsterr>rr-r<rrrpoll2s.        rBg>@FcCs|dkrt}n|r3ttdr3t}nt}|dkrbxJ|r^|||qHWn0x-|r|dkr||||d}qeWdS)Nr?r)r0hasattrr%rBr?)r:Zuse_pollr;countZpoll_funrrrloops      rFc@seZdZdZdZdZdZdZdZe dgZ ddddZ ddZ e Z ddd Zdd d Zejejd d ZdddZddZddZddZddZddZddZddZddZd d!Zd"d#Zd$d%Zd&d'Z d(d)d*Z!d+d,Z"d-d.Z#d/d0Z$d1d2Z%d3d4Z&d5d6Z'd7d8Z(d9d:Z)d;d<Z*d=d>Z+d?d@Z,dAdBZ-dS)C dispatcherFNwarningcCs|dkrt|_n ||_d|_|r|jd|j||d|_y|j|_Wqtk r}z:|j dt t fkrd|_n|j |WYdd}~XqXn d|_ dS)NrTF)r0_map_fileno setblocking set_socket connectedZ getpeernameaddrr*r+rr del_channelsocket)selfsockr;rrrr__init__s         zdispatcher.__init__c Cs|jjd|jjg}|jr?|jr?|jdn|jrX|jdn|jdk ry|jd|jWqtk r|jt|jYqXnddj |t |fS)N.Z listeningrMz%s:%dz <%s at %#x> ) __class__rrr6rNr5rM TypeErrorreprjoinid)rQZstatusrrr__repr__s  zdispatcher.__repr__cCs)|dkr|j}n|||jrrrrOs      zdispatcher.del_channelcCs?||f|_tj||}|jd|j|dS)Nr)Zfamily_and_typerPrKrL)rQZfamilytyperRrrr create_sockets zdispatcher.create_socketcCs)||_|j|_|j|dS)N)rPfilenorJr\)rQrRr;rrrrL%s zdispatcher.set_socketc CsRy9|jjtjtj|jjtjtjdBWntk rMYnXdS)NrC)rPZ setsockopt SOL_SOCKETZ SO_REUSEADDR getsockoptr*)rQrrrset_reuse_addr+s   zdispatcher.set_reuse_addrcCsdS)NTr)rQrrrr3<szdispatcher.readablecCsdS)NTr)rQrrrr4?szdispatcher.writablecCs=d|_tjdkr-|dkr-d}n|jj|S)NTnt)r6rnamerPlisten)rQZnumrrrrfFs  zdispatcher.listencCs||_|jj|S)N)rNrPbind)rQrNrrrrgLs zdispatcher.bindcCsd|_d|_|jj|}|tttfksT|tkratj dkra||_ dS|dt fkr||_ |j nt |t|dS)NFTrccer)zntrh)rM connectingrPZ connect_exrrrrrrerNr handle_connect_eventr*r)rQZaddressrrrrconnectPs     zdispatcher.connectcCsy|jj\}}Wn]tk r1dSYnRtk rx}z(|jdtttfkrcdSWYdd}~Xn X||fSdS)Nr)rPacceptrWr*r+rr r )rQZconnrNwhyrrrrl^s zdispatcher.acceptcCsy|jj|}|SWn`tk r|}z@|jdtkrFdS|jdtkrg|jdSWYdd}~XnXdS)Nr)rPsendr*r+rr,r))rQdataresultrmrrrrnls zdispatcher.sendcCs~y.|jj|}|s)|jdS|SWnItk ry}z)|jdtkrd|jdSWYdd}~XnXdS)Nr)rPrecvr)r*r+r,)rQZ buffer_sizerormrrrrrys  zdispatcher.recvcCsd|_d|_d|_|j|jdk ry|jjWqtk r}z$|jdtt fkrynWYdd}~XqXndS)NFr) rMr6rirOrPcloser*r+rr )rQrmrrrrss    zdispatcher.closec Csyt|j|}Wn.tk rFtd|jj|fYn9Xdi|jjd6|d6}tj|tdd|SdS)Nz!%s instance has no attribute '%s'zA%(me)s.%(attr)s is deprecated; use %(me)s.socket.%(attr)s insteadmeattr stacklevel)getattrrPAttributeErrorrVrwarningswarnDeprecationWarning)rQruZretattrmsgrrr __getattr__s zdispatcher.__getattr__cCstjjdt|dS)Nzlog: %s )sysstderrr"str)rQmessagerrrlogszdispatcher.loginfocCs*||jkr&td||fndS)Nz%s: %s)ignore_log_typesprint)rQrr]rrrlog_infoszdispatcher.log_infocCsP|jr|jn6|jsB|jr5|jn|jn |jdS)N)r6 handle_acceptrMrirj handle_read)rQrrrrs      zdispatcher.handle_read_eventcCs_|jjtjtj}|dkr?t|t|n|jd|_d|_dS)NrTF) rPrar`SO_ERRORr*rhandle_connectrMri)rQrrrrrjs    zdispatcher.handle_connect_eventcCs=|jr dS|js/|jr/|jq/n|jdS)N)r6rMrirj handle_write)rQrrrr!s    zdispatcher.handle_write_eventcCsB|jjtjtj}|dkr4|jn |jdS)Nr)rPrar`rr) handle_expt)rQrrrrr#s  zdispatcher.handle_expt_eventc Csnt\}}}}yt|}Wndt|}YnX|jd||||fd|jdS)Nz)<__repr__(self) failed for object at %0x>z:uncaptured python exception, closing channel %s (%s:%s %s)error)compact_tracebackrXrZrr))rQZniltvtbinfoZ self_reprrrrrszdispatcher.handle_errorcCs|jdddS)Nz!unhandled incoming priority eventrH)r)rQrrrrszdispatcher.handle_exptcCs|jdddS)Nzunhandled read eventrH)r)rQrrrrszdispatcher.handle_readcCs|jdddS)Nzunhandled write eventrH)r)rQrrrrszdispatcher.handle_writecCs|jdddS)Nzunhandled connect eventrH)r)rQrrrrszdispatcher.handle_connectcCs,|j}|dk r(|j|ndS)N)rlhandle_accepted)rQZpairrrrrs  zdispatcher.handle_acceptcCs|j|jdddS)Nzunhandled accepted eventrH)rsr)rQrRrNrrrrs zdispatcher.handle_acceptedcCs|jdd|jdS)Nzunhandled close eventrH)rrs)rQrrrr)szdispatcher.handle_close).rrrdebugrMr6riclosingrN frozensetrrSr[__str__r\rOrPZAF_INETZ SOCK_STREAMr^rLrbr3r4rfrgrkrlrnrrrsr~rrrrjr!r#rrrrrrrr)rrrrrGsN                       rGc@sReZdZddddZddZddZdd Zd d ZdS) dispatcher_with_sendNcCs tj|||d|_dS)Nrq)rGrS out_buffer)rQrRr;rrrrSszdispatcher_with_send.__init__cCs?d}tj||jdd}|j|d|_dS)Nri)rGrnr)rQZnum_sentrrr initiate_sendsz"dispatcher_with_send.initiate_sendcCs|jdS)N)r)rQrrrrsz!dispatcher_with_send.handle_writecCs|j pt|jS)N)rMlenr)rQrrrr4szdispatcher_with_send.writablecCsA|jr#|jdt|n|j||_|jdS)Nz sending %s)rrrXrr)rQrorrrrn!s zdispatcher_with_send.send)rrrrSrrr4rnrrrrrs    rcCstj\}}}g}|s0tdnxD|rv|j|jjj|jjjt|j f|j }q3W~|d\}}}dj dd|D}|||f|||fS)Nztraceback does not existrCrUcSsg|]}d|qS)z [%s|%s|%s]r).0xrrr <s z%compact_traceback..) rexc_infoAssertionErrorr5tb_framef_code co_filenameco_namer tb_linenotb_nextrY)rrtbrfileZfunctionlinerrrrr+s    rcCs|dkrt}nxt|jD]}y|jWq(tk r}z'|jdtkrgn |ssnWYdd}~Xq(tk rYq(|snYq(Xq(W|jdS)Nr) r0r1valuesrsr*r+r rclear)r;Z ignore_allrrrr close_all?s    rposixc@sseZdZddZddZddZddZd d d ZeZeZ d d Z ddZ d S) file_wrappercCstj||_dS)N)rdupr>)rQr>rrrrSfszfile_wrapper.__init__cCs4|jdkr&tjd|tn|jdS)Nrzunclosed file %r)r>rzr{ResourceWarningrs)rQrrr__del__iszfile_wrapper.__del__cGstj|j|S)N)rr r>)rQr+rrrrrnszfile_wrapper.recvcGstj|j|S)N)rr"r>)rQr+rrrrnqszfile_wrapper.sendNcCs9|tjkr)|tjkr)| r)dStddS)Nrz-Only asyncore specific behaviour implemented.)rPr`rNotImplementedError)rQlevelZoptnameZbuflenrrrrats zfile_wrapper.getsockoptcCs0|jdkrdStj|jd|_dS)NrrCr)r>rrs)rQrrrrsszfile_wrapper.closecCs|jS)N)r>)rQrrrr_szfile_wrapper.fileno) rrrrSrrrrnrar r"rsr_rrrrras      rc@s+eZdZdddZddZdS)file_dispatcherNc Cstj|d|d|_y|j}Wntk r@YnX|j|tj|tjd}|tj B}tj|tj |dS)NTr) rGrSrMr_ryset_filefcntlZF_GETFLr O_NONBLOCKZF_SETFL)rQr>r;r-rrrrSs    zfile_dispatcher.__init__cCs/t||_|jj|_|jdS)N)rrPr_rJr\)rQr>rrrrszfile_dispatcher.set_file)rrrrSrrrrrrs  r)/__doc__r%rPrr7rzrerrnorrrrrrrr r r r r rrr,r0rr ExceptionrKeyboardInterrupt SystemExitrr r"r$r/r?rBZpoll3rFrGrrrrerrrrrrr/sB      X        *:  '