m %Ec@sudZdkZdkZdkZdkZdkZdkZdklZdk Z dk l Z dk l Z l Z lZlZlZlZlZdklZdklZdklZdklZd klZd klZl Z d k!l"Z"l#Z#d k$l%Z%d k&l'Z'dk(l(Z(dk)l*Z*dZ+dZ,dZ-dZ.dZ/dZ0dZ1eZ2eZ3ei4i5dda6e7ei4i5ddZ8gZ9e'dZ:ddZ;dZ<e de=Z>dde?e?dde?d Z@d!eAfd"YZBd#efd$YZCd%ZDd&ZEd'ZFd(ZGd)efd*YZHd+efd,YZIe iJeCdS(-s Transient Object Container Class ('timeslice'-based design, no index). $Id: Transience.py 41203 2006-01-08 11:08:49Z andreasjung $ N(sescape(sHTMLFile(s TransientsDictionaryLikes ItemWithIds TTWDictionarys)ImmutablyValuedMappingOfPickleableObjectss#StringKeyedHomogeneousItemContainersTransientItemContainer(sLength(sOOBTree(sIOBTree(s Persistent(s SimpleItem(sClassSecurityInfosgetSecurityManager(snewSecurityManagerssetSecurityManager(snobody(s getLogger(sTransientObject(s FakeIOBTreesAdd Transient Object ContainersView management screenssAccess contents informationsCreate Transient ObjectssAccess Transient Objectss!Manage Transient Object Containerit Z_TOC_STRICTtt Z_TOC_DEBUGit TransiencecCs |adS(s0 Turn on assertions (which may cause conflicts) N(tontSTRICT(R((t=/data/zmath/zope/lib/python/Products/Transience/Transience.pyt setStrict@scGs|g}|itti|ittix!|D]}|it|q?Wdi|}t i |dS(Nt ( tsargstappendtstrtthreadt get_identttimetargstargtjointmsgtLOGtinfo(RR RR((RtTLOGEss dtml/addTransientObjectContaineric Cs_t|||||d|d|} |i || |dj o|i ||ddSndS(Rtlimitt period_secst update_menuiN(tTransientObjectContainertidttitlet timeout_minstaddNotificationtdelNotificationRRtobtselft _setObjecttREQUESTtNonet manage_main( R RRRRRRRR"R((Rt!constructTransientObjectContainerQs   tMaxTransientObjectsExceededcBstZRS(N(t__name__t __module__(((RR&[sRcBs-tZdZdZdZeeefZhdd<dd<ddWd4Z?d5Z@e ied6d7ZAe ied8d9ZBe ie d:dd;ZCd<ZDd=ZEe ied>d?ZFe ie d@dAZGe iedBdCZHe ie dDdEZIe iedFdGZJe ie dHdIZKe iedJdKZLe iedLdMZMe iedNdOZNe idPdQdRZOdSZPe ie dTddeeddedUZQdVZRRS(Xs] Object which contains items that are automatically flushed after a period of inactivity sTransient Object Containers"misc_/Transience/datacontainer.giftlabeltManagetactiontmanage_containerthelpRsTransience.stxtSecurityt manage_accesstManagert AnonymoustSessionss#dtml/manageTransientObjectContaineritdenyRicCsW||_||_|i|||i||i||i ||i dS(N( RR Rt _setTimeoutRRt _setLimitRtsetDelNotificationTargetRtsetAddNotificationTargetRt_reset(R RRRRRRR((Rt__init__s     cCs(t|tdj ott| dfnt|tdj ott| dfn|d}|djos|djotdn||jotd||fn||djotd||fqn||_||_ t t i t |||_dS(NisMust be integeri<isresolution cannot be 0sBresolution cannot be greater than timeout minutes * 60 ( %s > %s )s@timeout seconds (%s) must be evenly divisible by resolution (%s)(ttypeRt TypeErrortescapeRt timeout_secst ValueErrorR t _timeout_secst_periodtinttmathtceiltfloatt_timeout_slices(R RRR=((RR4s      cCs@t|tdj ott| dfn||_dS(NisMust be integer(R:RR;R<R t_limit(R R((RR5scCst|_|io\tt|itd|i}x|D]}t |i| Call finalization handlers for the data in each stale bucket s%_finalize: doing nothing (no timeout)Nis,_finalize: could not acquire lock, returnings%_finalize: lock acquired successfullys<_finalize: start_finalize (%s) >= max_ts (%s), doing nothingsD_finalize: start_finalize (%s) <= max_ts (%s), finalization possible(R RER\Rt finalize_locktacquireRRtlast_finalizedR@tstart_finalizeRRYRt_do_finalize_worktrelease(R RYRRR((Rt _finalize s&     c Csto tdtotd|totd|totd|t|ii||}totd| d}x|D]}t ||jt ||jt ot |ii|t|i|i}totd|t| f|t|7}x|D]}|i|q#WqW|o|ii|ntotd||ii|dS( Ns_do_finalize_work: enterings_do_finalize_work: now is %ss_do_finalize_work: max_ts is %ss'_do_finalize_work: start_finalize is %ss$_do_finalize_work: to_finalize is %sis5_do_finalize_work: values to notify from ts %s are %ssD_do_finalize_work: setting _last_finalized_timeslice to max_ts of %s(R\RRYRRRoR RHRpt to_finalizetdeltatkeyRiRRjRtlenR{t notifyDelRTt decrementRRRU( R RYRRRR{RRR((RR>s,"cCs[|i}t|i}||i}|i|}|i ||||i |dS(N( R RRRRJR@RYRRRRt _do_gc_work(R RRRYR((Rt_invoke_finalize_and_gcbs   cCs:|ipto tddSn|i|}|iid}z|oM|oto tdnto td|i }|i ||n|obto td|i }||i }||i }t||do|i ||qnto tddSWd|o|iinXdS( s' Add 'fresh' future or current buckets s&_replentish: no timeout, doing nothingNis%_replentish: required, lock acquired)s)_replentish: required, lock NOT acquired)s;_replentish: attempting optional replentish (lock acquired)soptional replentishs=_optional replentish attempt aborted, could not acquire lock.(R RER\RRgRYRtreplentish_lockRt lock_acquiredRQRt_do_replentish_workR@RRtrollR(R RYRRRRR((RRhks2     c Csto td|||i}totd|totd|totd||tjo#totd|tfdSn||jo|}||it}n#||i}||itd}totd|totd||||i}t |||i}|i to t|totd |totd |x<|D]4}tot|ii| t|i|= SPARE_BUCKETS (%s), doing nothingis*_do_replentish_work: replentish_start = %ss(_do_replentish_work: replentish_end = %ss*_do_replentish_work: adding %s new bucketss(_do_replentish_work: buckets to add = %s(R\RRRYR R@tavailable_sparesRKtreplentish_starttreplentish_endtnRIt new_bucketsRxRRiRbRHRjRNRQRURP( R RYRRRRRRbR((RRs4    cCs(|ipdSntdddpto tddSn|iidpto tddSnz|djot |i }n|i }|i t td}|||jo&totd|||fdSn,totd |||f|i|Wd|iiXdS( s Remove stale buckets Niitgcs_gc: lost roll, doing nothings_gc: couldnt acquire lockf2.0s3_gc: gc attempt not yet required ( (%s - %s) < %s )s_gc: (%s -%s) > %s, gc invoked(R RERR\Rtgc_lockRRYR#RJR@RStlast_gctroundRKtgc_everyRR(R RYRR((Rt_gcs*   cCsto td|i}totd|t|iid|}totdt |xZ|D]R}t ||jt ot |ii|totd||i|=qoWtotd||ii|dS(Ns_do_gc_work: enterings_do_gc_work: max_ts is %ss_do_gc_work: to_gc is: %ss#_do_gc_work: deleting %s from _datas,_do_gc_work: setting last_gc_timeslice to %s(R\RR RRRRoRHRpR#tto_gcR RRiRRjRYRSRU(R RYRRR((RRs cCsStotd||i|i}|djodSn|i||ddS(NsnotifyAdd with %sR( R\RRR t _getCallbackt _addCallbacktcallbackR#t_notify(R RR((RRs  cCsStotd||i|i}|djodSn|i||ddS(NsnotifyDel with %sR( R\RRR Rt _delCallbackRR#R(R RR((RRs  cCs|pdSnt|tdjouy|i|}Wqttfj oI|i}d}t i ||di |fdtidSqXn|}|S(NRs2No such onAdd/onDelete method %s referenced via %st/texc_info(RR#R:R tunrestrictedTraversetmethodRRVtgetPhysicalPathtpathterrRRRtsysR(R RRRR((RRs  cCst|ot}zs|i}ytdt|||WnB|i }t id||di|fdtinXWdt|XnBd}|i }t i||di||fdtidS(Ns%s failed when calling %s in %sRRs*%s in %s attempted to call non-callable %s(tcallableRtgetSecurityManagertsmtgetUsertusertnewSecurityManagerR#tnobodyRR RRRRtnameRRRtsetSecurityManagerR(R RRRRRRR((RR&s"      cCs|iS(N(R R(R ((RR<stnew_or_existingcCsatotd||i|t}|tjo)t|}|||<|i|}n|S(Nsnew_or_existing called with %s( R\RRR R`RRtTransientObjectR|(R RR((RR@s   tnewcCstotd|t|tdj ot|dfn|i|otd|nt|}|||<|i |S(Nsnew called with %sRskey is not a string typescannot duplicate key %s( R\RRR:R;R RjRRRR|(R RR((RRJs  tsetTimeoutMinutescCsR|d}||ijp||ijo|i|||indS(s The period_secs parameter is defaulted to preserve backwards API compatibility. In older versions of this code, period was hardcoded to 20. i<N(RR=R tgetTimeoutMinutesRtgetPeriodSecondsR4R8(R RRR=((RRWs  &cCs |idS(Ri<N(R R?(R ((RRcscCs|iS(RN(R R@(R ((RRgstgetSubobjectLimitcCs|iS(RN(R RF(R ((RRlstsetSubobjectLimitcCs(||ijo|i|ndS(RN(RR RR5(R R((RRqstgetAddNotificationTargetcCs|ipdS(NR(R R(R ((RRwsR7cCs ||_dS(N(tfR R(R R((RR7{stgetDelNotificationTargetcCs|ipdS(NR(R R(R ((RRsR6cCs ||_dS(N(RR R(R R((RR6stdisableInbandHousekeepingcCs t|_dS(s' No longer perform inband housekeeping N(RR Rd(R ((RRstenableInbandHousekeepingcCs t|_dS(s (Re)enable inband housekeeping N(RvR Rd(R ((RRstisInbandHousekeepingEnabledcCs|iS(s* Report if inband housekeeping is enabled N(R Rd(R ((RRstViewt housekeepcCs|it|idS(s Call this from a scheduler at least every self._period * (SPARE_BUCKETS - 1) seconds to perform out of band housekeeping N(R ReRJR@(R ((RRscCs+|i||i||i|dS(N(R RRYRhR(R RY((RRes  t%manage_changeTransientObjectContainercCs||_|i|||i||p d}n|p d}n|i ||i ||dj o|i ||ddSndS(s0 Change an existing transient object container. tmanage_tabs_messagesChanges saved.N(RR RRRRRRR#RR7R6R"R,(R RRRRRRR"((RRs       cCsx|idp)|idt}||_|_n|d}t |t o#|}t||_|_n|idp d|_ n|idpst t|i td|i }x5|D]-}|ii|pt|i|R\RtreasonRvR(RRRR]((RRs  !!cCs|p tndS(N(tcasetAssertionError(R((RRisROcBsDtZdZdZdZdZdZdZdZRS(s A persistent object representing a typically increasing integer that has conflict resolution which uses the greatest integer out of the three available states. cCs ||_dS(N(R{R tvalue(R R{((RR9scCs ||_dS(N(R{R R(R R{((RRU scCs|iS(N(R R(R ((Rt __getstate__#scCs ||_dS(N(R{R R(R R{((RR&scCs|iS(N(R R(R ((Rt__call__)scCst|||S(N(RPtoldtstate1tstate2(R RRR((Rt_p_resolveConflict,s( R'R(RR9RURRRR (((RROs      RWcBsYtZdZddZdZdZdZdZdZdZ d Z RS( s A persistent object responsible for maintaining a repesention of the number of current transient objects. Conflict resolution is sensitive to which methods are used to change the length. icCs|i|dS(N(R RUR(R R((RR98scCs||_d|_||_dS(Ni(RR Rtceiling(R R((RRU;s  cCs"|i|7_|i|7_dS(scIncrease the length by delta. Conflict resolution will take the sum of all the increments.N(R R RR(R R((RR@scCs"|i|7_|i|8_dS(s[Decrease the length by delta. Conflict resolution will take the highest decrement.N(R RRR(R R((RRGscCs|iS(N(R R(R ((RRNscCs|ii|dS(N(R RRR(R R((RRQscCs|iS(N(R R(R ((RRTscCsZ|d|d|d|d