3 \N @shdZddlZddlZddlZddlZddlZddlZddlmZm Z m Z m Z m Z m Z mZmZmZmZmZmZmZee e eeeehZyeWnek riZYnXddZGdddeZeeefZdd Zd d Z d d Z!ddZ"d&ddZ#d'ddZ$e$Z%d(ddZ&GdddZ'Gddde'Z(ddZ)d)dd Z*ej+d!krdGd"d#d#Z,Gd$d%d%e'Z-dS)*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 Cs>y tj|Stttfk r8|tkr0t|Sd|SXdS)NzUnknown error %s)osstrerror ValueError OverflowError NameErrorr)errr /usr/lib64/python3.6/asyncore.py _strerrorDs  rc@s eZdZdS)ExitNowN)__name__ __module__ __qualname__rrrrrLsrc 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$cCsyX|tj@r|j|tj@r&|j|tj@r8|j|tjtjBtj B@rV|j Wnht k r}z&|j dt kr|jn|j WYdd}~Xn(tk rYn|jYnXdS)Nr)selectPOLLINrPOLLOUTr!POLLPRIr#ZPOLLHUPZPOLLERRZPOLLNVAL handle_closeOSErrorargs _DISCONNECTEDrr)rflagserrr readwriteis"     r/c CsN|dkr t}|rJg}g}g}x^t|jD]N\}}|j}|j}|rR|j||rh|j rh|j||sp|r,|j|q,Wg|ko|ko|knrtj|dSt j ||||\}}}x(|D] }|j |}|dkrqt |qWx*|D]"}|j |}|dkrqt |qWx.|D]&}|j |}|dkr<q t |q WdS)N) socket_maplistitemsreadablewritableappend acceptingtimeZsleepr%getr r"r$) timeoutmaprwr.fdrZis_rZis_wrrrpoll}sD   "           r?cCs|dkr t}|dk r t|d}tj}|rx^t|jD]N\}}d}|jr^|tjtjBO}|j rx|j rx|tj O}|r:|j ||q:W|j|}x.|D]&\}}|j |}|dkrqt||qWdS)Nir)r1intr%r?r2r3r4r&r(r5r7r'registerr9r/)r:r;Zpollsterr>rr-r<rrrpoll2s(    rB>@FcCsj|dkr t}|r ttdr t}nt}|dkrBx8|r>|||q.Wn$x"|rd|dkrd||||d}qDWdS)Nr?r)r1hasattrr%rBr?)r:Zuse_pollr;countZpoll_funrrrloops rGc@s6eZdZdZdZdZdZdZdZe dhZ dAddZ ddZ e Z dBdd ZdCd d Zejejfd d ZdDddZddZddZddZddZddZddZddZddZd d!Zd"d#Zd$d%ZdEd'd(Z 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,dS)F dispatcherFNwarningcCs|dkrt|_n||_d|_|r|jd|j||d|_y|j|_Wqtk r}z,|j dt t fkrvd|_n |j |WYdd}~XqXnd|_ dS)NrTF)r1_map_fileno setblocking set_socket connectedZ getpeernameaddrr*r+rr del_channelsocket)selfsockr;rrrr__init__s    zdispatcher.__init__c Cs|jjd|jjg}|jr.|jr.|jdn|jr>|jd|jdk ry|jd|jWn$tk r|jt|jYnXddj |t |fS)N.Z listeningrNz%s:%dz <%s at %#x> ) __class__rrr7rOr6rN TypeErrorreprjoinid)rRZstatusrrr__repr__s    zdispatcher.__repr__cCs|dkr|j}|||j<dS)N)rJrK)rRr;rrr add_channel szdispatcher.add_channelcCs,|j}|dkr|j}||kr"||=d|_dS)N)rKrJ)rRr;r>rrrrPs zdispatcher.del_channelcCs.||f|_tj||}|jd|j|dS)Nr)Zfamily_and_typerQrLrM)rRZfamilytyperSrrr create_sockets   zdispatcher.create_socketcCs||_|j|_|j|dS)N)rQfilenorKr])rRrSr;rrrrM s zdispatcher.set_socketc CsDy*|jjtjtj|jjtjtjdBWntk r>YnXdS)NrD)rQZ setsockopt SOL_SOCKETZ SO_REUSEADDR getsockoptr*)rRrrrset_reuse_addr&s zdispatcher.set_reuse_addrcCsdS)NTr)rRrrrr47szdispatcher.readablecCsdS)NTr)rRrrrr5:szdispatcher.writablecCs(d|_tjdkr|dkrd}|jj|S)NTnt)r7rnamerQlisten)rRZnumrrrrgAszdispatcher.listencCs||_|jj|S)N)rOrQbind)rRrOrrrrhGszdispatcher.bindcCspd|_d|_|jj|}|tttfks8|tkrBtj dkrB||_ dS|dt fkr^||_ |j nt |t|dS)NFTrdr)rN connectingrQZ connect_exrrrrrrfrOr handle_connect_eventr*r)rRZaddressrrrrconnectKs   zdispatcher.connectcCsny|jj\}}WnNtk r&dStk r`}z |jdtttfkrNdSWYdd}~Xn X||fSdS)Nr)rQacceptrXr*r+rr r )rRZconnrOwhyrrrrlYszdispatcher.acceptcCsfy|jj|}|Stk r`}z4|jdtkr4dS|jdtkrN|jdSWYdd}~XnXdS)Nr)rQsendr*r+rr,r))rRdataresultrmrrrrngs zdispatcher.sendcCshy$|jj|}|s|jdS|SWn>tk rb}z"|jdtkrP|jdSWYdd}~XnXdS)Nr)rQrecvr)r*r+r,)rR buffer_sizerormrrrrrts zdispatcher.recvcCsnd|_d|_d|_|j|jdk rjy|jjWn6tk rh}z|jdtt fkrXWYdd}~XnXdS)NFr) rNr7rirPrQcloser*r+rr )rRrmrrrrts zdispatcher.closecCstjjdt|dS)Nzlog: %s )sysstderrr"str)rRmessagerrrlogszdispatcher.loginfocCs||jkrtd||fdS)Nz%s: %s)ignore_log_typesprint)rRrxr^rrrlog_infos zdispatcher.log_infocCs:|jr|jn&|js.|jr$|j|jn|jdS)N)r7 handle_acceptrNrirj handle_read)rRrrrrs  zdispatcher.handle_read_eventcCs@|jjtjtj}|dkr(t|t||jd|_d|_dS)NrTF) rQrbraSO_ERRORr*rhandle_connectrNri)rRrrrrrjs zdispatcher.handle_connect_eventcCs*|jr dS|js|jr|j|jdS)N)r7rNrirj handle_write)rRrrrr!s zdispatcher.handle_write_eventcCs0|jjtjtj}|dkr$|jn|jdS)Nr)rQrbrarr) handle_expt)rRrrrrr#s zdispatcher.handle_expt_eventc CsXt\}}}}y t|}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_tracebackrYr[r}r))rRZniltvtbinfoZ self_reprrrrrs zdispatcher.handle_errorcCs|jdddS)Nz!unhandled incoming priority eventrI)r})rRrrrrszdispatcher.handle_exptcCs|jdddS)Nzunhandled read eventrI)r})rRrrrrszdispatcher.handle_readcCs|jdddS)Nzunhandled write eventrI)r})rRrrrrszdispatcher.handle_writecCs|jdddS)Nzunhandled connect eventrI)r})rRrrrrszdispatcher.handle_connectcCs|j}|dk r|j|dS)N)rlhandle_accepted)rRZpairrrrr~szdispatcher.handle_acceptcCs|j|jdddS)Nzunhandled accepted eventrI)rtr})rRrSrOrrrrszdispatcher.handle_acceptedcCs|jdd|jdS)Nzunhandled close eventrI)r}rt)rRrrrr)s zdispatcher.handle_close)NN)N)N)N)rz)-rrrdebugrNr7riclosingrO frozensetr{rTr\__str__r]rPrQZAF_INETZ SOCK_STREAMr_rMrcr4r5rgrhrkrlrnrrrtryr}rrjr!r#rrrrrr~rr)rrrrrHsL          rHc@s6eZdZd ddZddZddZdd Zd d ZdS) dispatcher_with_sendNcCstj|||d|_dS)Nrq)rHrT out_buffer)rRrSr;rrrrTszdispatcher_with_send.__init__cCs.d}tj||jdd}|j|d|_dS)Nri)rHrnr)rRZnum_sentrrr initiate_sendsz"dispatcher_with_send.initiate_sendcCs |jdS)N)r)rRrrrrsz!dispatcher_with_send.handle_writecCs|j pt|jS)N)rNlenr)rRrrrr5 szdispatcher_with_send.writablecCs0|jr|jdt||j||_|jdS)Nz sending %s)rr}rYrr)rRrorrrrns zdispatcher_with_send.send)NN)rrrrTrrr5rnrrrrrs  rcCstj\}}}g}|stdx0|rN|j|jjj|jjjt|j f|j }q W~|d\}}}dj dd|D}|||f|||fS)Nztraceback does not existrDrVcSsg|] }d|qS)z [%s|%s|%s]r).0xrrr )sz%compact_traceback..) ruexc_infoAssertionErrorr6tb_framef_code co_filenameco_namerw tb_linenotb_nextrZ)rrtbrfileZfunctionlinerzrrrrs rcCs|dkr t}x~t|jD]n}y |jWqtk rb}z|jdtkrLn|sRWYdd}~Xqtk rvYq|sYqXqW|jdS)Nr) r1r2valuesrtr*r+r rclear)r;Z ignore_allrrrr close_all,s   rposixc@sNeZdZddZddZddZddZdd d ZeZeZ d d Z ddZ d S) file_wrappercCstj||_dS)N)rdupr>)rRr>rrrrTQszfile_wrapper.__init__cCs*|jdkrtjd|t|d|jdS)Nrzunclosed file %r)source)r>warningswarnResourceWarningrt)rRrrr__del__Ts  zfile_wrapper.__del__cGstj|jf|S)N)rr r>)rRr+rrrrrZszfile_wrapper.recvcGstj|jf|S)N)rr"r>)rRr+rrrrn]szfile_wrapper.sendNcCs*|tjkr|tjkr| rdStddS)Nrz-Only asyncore specific behaviour implemented.)rQrarNotImplementedError)rRlevelZoptnameZbuflenrrrrb`s   zfile_wrapper.getsockoptcCs(|jdkrdS|j}d|_tj|dS)NrrDr)r>rrt)rRr>rrrrtks  zfile_wrapper.closecCs|jS)N)r>)rRrrrr`rszfile_wrapper.fileno)N) rrrrTrrrrnrbr r"rtr`rrrrrLs rc@seZdZdddZddZdS)file_dispatcherNc CsPtj|d|d|_y |j}Wntk r4YnX|j|tj|ddS)NTF)rHrTrNr`AttributeErrorset_filer set_blocking)rRr>r;rrrrTws  zfile_dispatcher.__init__cCs"t||_|jj|_|jdS)N)rrQr`rKr])rRr>rrrrs  zfile_dispatcher.set_file)N)rrrrTrrrrrrus r)r0N)r0N)rCFNN)NF).__doc__r%rQrur8rrerrnorrrrrrrr r r r r rrr,r1rr ExceptionrKeyboardInterrupt SystemExitrr r"r$r/r?rBZpoll3rGrHrrrrfrrrrrr/sB<    '  -  )