m MEc@sdZdkZdkZdkZdkZdkZdkZdkZdkZdk l Z dk l Z dk lZlZdklZdklZlZlZdklZdklZd klZd klZlZd klZl Z l!Z!d k"l#Z#d k$l%Z%l&Z&dk'l(Z(ei)dZ*da+dZ,ei-e.e/dZ0defdYZ1dfdYZ2dfdYZ3dfdYZ4dei5fdYZ6dZ7dei5fdYZ8dS( sThe StorageServer class and the exception that it may raise. This server acts as a front-end for one or more real storages, like file storage or Berkeley storage. TODO: Need some basic access control-- a declaration of the methods exported for invocation by the server. N(s ClientStub(s CommitLog(s StorageStatss StatsServer(s Dispatcher(sManagedServerConnectionsDelaysMTDelay(strigger(s AuthError(sResolvedSerial(s StorageErrorsStorageTransactionError(sTransactionErrors ReadOnlyErrors ConflictError(s referencesf(su64soid_repr(sBLATHERsZEO.StorageServertcCsdtiadS(s?Internal helper to reset the logging label (e.g. after fork()).s%sN(tostgetpidt_label(((t0/data/zmath/zope/lib/python/ZEO/StorageServer.pyt set_label6scCsB|pt}|od||f}nti||d|dS(s!Internal helper to log a message.s(%s) %stexc_infoN(tlabelRtmessagetloggertlogtlevelR(RR RR((RR ;s  tStorageServerErrorcBstZdZRS(s7Error reported when an unpicklable exception is raised.(t__name__t __module__t__doc__(((RR Bs t ZEOStoragecBstZdZeiZgZdedZdZ dZ dZ dZ dZ eiedZd Zed Zd Zd Zd ZdZdZdZdZdZdZdZdZdZddZ dZ!ddZ"dZ#dZ$eddZ%d Z&d!Z'd"Z(d#Z)d$Z*d%Z+d&Z,d'Z-d(Z.d)Z/d*Z0d+Z1d,Z2d-Z3d.Z4d/Z5ed0Z6d1Z7d2Z8RS(3s7Proxy to underlying storage for a single remote client.icCs||_d|_d|_d|_d|_d|_d|_d|_ ||_ d|_ d|_ d|_ t|_d|_||_h|_x!|iD]}d|i|i( RRtreprtidttidRt _transactiontstidRt __class__R tname(RR@R<R>((Rt__repr__s  & cCs#t|d|d|id|dS(NR RR(R tmsgR RR R(RRBR R((RR scCs5|ii|_|ii|_|ii|_|ii|_|ii|_|ii|_|ii|_t |idd}|dj o ||_ ny|ii }Wntj onfX|}|ii|xH|iD]:}t|| ptt||t |i|qW|ii|_dS(s'Delegate several methods to the storagetrecord_iternextN(RRt versionEmptytversionst getSerialthistorytloadt loadSerialtmodifiedInVersiontgetattrRRCtgetExtensionMethodstfntAttributeErrortdR#tupdatetkeysR@thasattrtAssertionErrortsetattrtlastTransaction(RRCRORMR@((Rtsetup_delegations,     cCs |io tn|idjoWtiiii }|i d|dt i |dj o|d|q~dSn|ii|joutiiii }|i d|t|t|iift i |dj o||ii|qdSndS(Nsno current transaction: %s()R is(%s(%s) invalid; current transaction = %si(RRt ReadOnlyErrorRRtsyst _getframetf_backtf_codetco_nametcallerR tloggingtWARNINGtexcR<R;R:(RR<R`R]((Rt _check_tids"     (  cCs-|ii}| p |djodSn|S(sReturn string specifying name of authentication module to use. The module name should be auth_%s where %s is auth_protocol.tnoneN(RRt auth_protocoltprotocolR(RRd((RtgetAuthProtocols  cCs|io|i otdn|idj o|idtdn|ii i |}|djo%|id|td|n| o$|i p |i o tn|i p||_ ||_ ||_|i|ii||\|_|_dS(sSelect the storage that this client will use This method must be the first one called by the client. For authenticated storages this method will be called by the client immediately after authentication is finished. s+Client was never authenticated with server!sduplicate register() callsunknown storage_id: %ssunknown storage: %sN(RR"R!t AuthErrorRRR t ValueErrorRtstoragestgetRRt isReadOnlyRWRVtregister_connectionRR(RRRR((Rtregisters$       cCshdt|i<d|ii<d|ii<d|ii<d|ii<d|i<dt|ds(RRaR;RRRt_wait(RR;((RRtvotes csHi|dtioiSnidSdS(NR`cs iS(N(Rt _abortVersiontsrc((RR(RRs(RRaR;RRRRR(RRR;((RRRt abortVersions csNi|dtioiSnidSdS(NR`csiS(N(Rt_commitVersionRtdest((RRR(RRs( RRaR;RRRRRR(RRRR;((RRRRt commitVersions csHi|dtioiSnidSdS(NR`cs iS(N(Rt_undottrans_id((RR(RRs(RRaR;RRRRR(RRR;((RRRtundos cCsEd|_|ii|ti|i_|ii|||dS(Ni( RRRtbeginRRRRRttxnR<R(RRR<R((Rt _tpc_begins c Csd}y%|ii|||||i }Wn(t t fj o n5t j o}d|_t|to<|iid7_|idt|t|ftnt|tp+|idtid tidtnti}d|_ y|i!|dWn6dt"|}|i|tit$|}nX|}n)X|djo|i%i&||fn|t'jo0|ii(d7_(|idt|tn|i)i&||f|djS( Nisconflict error oid=%s msg=%ssstore error: %s, %siRs%Couldn't pickle storage exception: %stsconflict resolved oid=%s(*RterrRRRRzRRR{Rt newserialt SystemExittKeyboardInterruptt ExceptionRR0t ConflictErrorRt conflictsR toid_reprR4RtTransactionErrorRXRR^tERRORtTruetcPickletPicklertpicklertfasttdumpR:RBR RtappendtResolvedSerialtconflicts_resolvedR( RRzRRR{RRRBR((Rt_stores>       cCs8|ii|i|iodSn|ii|iS(N(RRt serialnosRRRttpc_voteR(R((RRs cCs_|ii||i\}}g}|D]}|||fq)~}|i i |||fS(N( RRRRRR<toidsRRztinvRtextend(RRRzRRR<R((RR#s'cCs|ii|||i\}}g}|D]}|||fq,~}|i i ||o;g}|D]}|||fqj~}|i i |n||fS(N( RRRRRRR<RRRzRRR(RRRRzRRR<R((RR)s!''cCs_|ii||i\}}g}|D]}||dfq)~}|i i |||fS(N( RRRRRR<RRRzRRRR(RRRzRRR<R((RR2s'cCs{||_|iioGt}|iii||f|i dt |ii|Sn|i dt |i SdS(Ns=Transaction blocked waiting for storage. Clients waiting: %d.s"Transaction acquired storage lock.( tthunkRt_thunkRR=tDelayRORRR RsRt_restart(RRRO((RRBs   cCs|iidjo d}nd}|i||ii|iifdt|i|i|i |i |ii \}}x/t|D]!}|i|ipPqqW|i}|dj o|i|n|SdS(Nis4Preparing to commit transaction: %d object, %d bytess5Preparing to commit transaction: %d objects, %d bytesR (RRRttemplateR RnRRRR<Rt get_loaderRxtloaderRRRRHRtresptdelayRtreply(RRRRRRxR((RROs "     cCsx|iio{|iiid\}}|i||oI|iio't|ii}|i d|n|i ddSqqWdS(Nis3Blocked transaction restarted. Clients waiting: %dsBlocked transaction restarted.( RRRtpopRt zeo_storaget_restart_otherRsRR (RRRR((RRcs   cCsPy|i|Wn4|iddtidt|ii dSnXdSdS(Ns-Unexpected error handling waiting transactionR Rii( RRRRR R^R_RRR(RRR((RRps  (9R RRt ClientStubt ClientStorageR.R$RR'R(R*R5R9RAR^tINFOtFalseR RVRaReRlRvRwRLRyR|RRRRRRRRRRRRRRR7RRRRRRRRRRRRRRR(((RREsb                !             &    t StorageServercBstZdZeZeZeZdde e e e e dZ dZ dZ dZ fe dZdZd Zd ZRS( s3The server side implementation of ZEO. The StorageServer is the 'manager' for incoming connections. Each connection is associated with its own ZEOStorage instance (defined below). The StorageServer may handle multiple storages; each ZEOStorage instance only handles a single storage. iidc Cs||_||_tdig} |iD]:\} } | d| | i odpd| i fq0~ } t d|i i|odpd| fx|iD]}g|_qW||_||_||_| |_d|_|o|i|ng|_||_h|_|i|d|i|_h|_ h|_!xd|ii"D]S} t#|i | <|djo t%}nt'|}|i(||i!| Wx/ti iD]}y|iWqbqbXqbWdS(s}Close the dispatcher so that there are no new connections. This is only called from the test suite, AFAICT. N( RRRRRRhR Rtasyncoret socket_mapR(RRR((Rt close_server~s cCsBx;|iiD]*}|i|jo|i|iqqWdS(s|Internal: remove the given connection from self.connections. This is the inverse of register_connection(). N(RRR tclR-tobjtremove(RR-R3((Rt close_conns (R RRt DispatcherRRR!tManagedServerConnectionR$RR'R RRkRRR2R6(((RR~s l "    RcBstZdZdZRS(NcCsdS(N((RR((RRscCsdS(N((RR((RRs(R RRR(((RRs RcBs2tZdZdZdZdZdZRS(s5Monitors transaction progress and generates timeouts.cCsWtii||id||_d|_d|_ ti |_ t |_ dS(Ni(RRR'Rt setDaemonRt_timeoutRt_clientt _deadlinet Conditiont_condttriggert_trigger(RR((RR's    cCsi|iizG|idjpt||_ti|i|_ |ii Wd|ii XdS(N( RR>tacquireR;RRSRRR:R<tnotifytrelease(RR((RRs  cCsf|iizD|idj pt|i|jptd|_d|_Wd|iiXdS(N( RR>RAR;RRSRR<RC(RR((RRs   csx|iiz_x"|idjo|iiqW|iti}|djo d|_n|iWd|ii X|djo.i d|i |i idqti|qWdS(Niis$Transaction timeout after %s secondscs iiS(N(RRR((R(RRs(RR>RAR<RRRthowlongR;RRCR R:R@t pull_triggertsleep(RRRD((RRtruns"     (R RRR'RRRG(((RRs  cGs t||}|i|iS(N(tSlowMethodThreadtmethodRRRR(RIRR((RRs RHcBs tZdZdZdZRS(sThread to run potentially slow storage methods. Clients can use the delay attribute to access the MTDelay object used to send a zrpc response at the right time. cCs2tii|||_||_t|_ dS(N( RRR'RRIt_methodRt_argstMTDelayR(RRIR((RR's  cCsqy|i|i}WnDttfj o n:tj o|iit i nX|ii |dS(N( RRJRKtresultRRRRterrorRXRR(RRM((RRGs(R RRR'RG(((RRHs  (9RR0RRRXRRR^RtZEORt ZEO.CommitLogRt ZEO.monitorRRtZEO.zrpc.serverR7tZEO.zrpc.connectionR8RRLtZEO.zrpc.triggerR?tZEO.ExceptionsRftZODB.ConflictResolutionRtZODB.POSExceptiont StorageErrorRRRWRtZODB.serializeRt ZODB.utilsRRtZODB.loglevelsRt getLoggerR RRRRRR R RRRRRRRH(&RHR0RRRRRRRLRRfRR R?RRRR7RRRRRRRXRR8R RR RR^RRWRRRXR((Rt?sF                 ;<