/* Ċ Ġ* ĠCopyright Ġ 2 0 1 7 Ġthe Ġoriginal Ġauthor Ġor Ġauthors . Ċ Ġ* Ċ Ġ* ĠLicensed Ġunder Ġthe ĠApache ĠLicense , ĠVersion Ġ 2 . 0 Ġ( the Ġ" License "); Ċ Ġ* Ġyou Ġmay Ġnot Ġuse Ġthis Ġfile Ġexcept Ġin Ġcompliance Ġwith Ġthe ĠLicense . Ċ Ġ* ĠYou Ġmay Ġobtain Ġa Ġcopy Ġof Ġthe ĠLicense Ġat Ċ Ġ* Ċ Ġ* ĠĠĠĠĠ Ġhttp :// www . apache . org / licenses / LICENSE - 2 . 0 Ċ Ġ* Ċ Ġ* ĠUnless Ġrequired Ġby Ġapplicable Ġlaw Ġor Ġagreed Ġto Ġin Ġwriting , Ġsoftware Ċ Ġ* Ġdistributed Ġunder Ġthe ĠLicense Ġis Ġdistributed Ġon Ġan Ġ" AS ĠIS " ĠBASIS , Ċ Ġ* ĠWITHOUT ĠWARRANTIES ĠOR ĠCONDITIONS ĠOF ĠANY ĠKIND , Ġeither Ġexpress Ġor Ġimplied . Ċ Ġ* ĠSee Ġthe ĠLicense Ġfor Ġthe Ġspecific Ġlanguage Ġgoverning Ġpermissions Ġand Ċ Ġ* Ġlimitations Ġunder Ġthe ĠLicense . Ċ Ġ*/ Ċ package Ġcom . github . bur run an . s 3 cache . internal Ċ Ċ import Ġcom . amazonaws . services . s 3 . Amazon S 3 Ċ import Ġcom . amazonaws . services . s 3 . model . Amazon S 3 Exception Ċ import Ġcom . amazonaws . services . s 3 . model . Object Metadata Ċ import Ġcom . amazonaws . services . s 3 . model . Put Object Request Ċ import Ġcom . amazonaws . services . s 3 . model . Storage Class Ċ import Ġorg . gradle . api . logging . LogLevel Ċ import Ġorg . gradle . api . logging . Logging Ċ import Ġorg . gradle . caching .* Ċ import Ġorg . gradle . util . Gradle Version Ċ import Ġjava . io . ByteArray InputStream Ċ import Ġjava . io . ByteArray OutputStream Ċ import Ġjava . io . IOException Ċ import Ġjava . util .* Ċ import Ġkotlin . math . absolute Value Ċ Ċ private Ġval Ġlogger Ġ= ĠLogging . getLogger ( Aws S 3 Build Cache Service :: class . java ) Ċ Ċ class ĠAws S 3 Build Cache Service Ġinternal Ġconstructor ( ĊĠĠĠ Ġprivate Ġval Ġs 3 : ĠAmazon S 3 , ĊĠĠĠ Ġprivate Ġval Ġbucket Name : ĠString , ĊĠĠĠ Ġprivate Ġval Ġprefix : ĠString ?, ĊĠĠĠ Ġprivate Ġval Ġreduced Red undancy : ĠBoolean , ĊĠĠĠ Ġprivate Ġval Ġmaximum Cached Object Length : ĠLong , ĊĠĠĠ Ġprivate Ġval Ġshow Statistics : ĠBoolean , ĊĠĠĠ Ġprivate Ġval Ġshow Statistics When Impact Ex ceeds : ĠLong , ĊĠĠĠ Ġprivate Ġval Ġshow Statistics When S avings Ex ceeds : ĠLong , ĊĠĠĠ Ġprivate Ġval Ġshow Statistics When W aste Ex ceeds : ĠLong , ĊĠĠĠ Ġprivate Ġval Ġshow Statistics When Transfer Ex ceeds : ĠLong Ċ ) Ġ: ĠBuild Cache Service Ġ{ ĊĠĠĠ Ġcompanion Ġobject Ġ{ ĊĠĠĠĠĠĠĠ Ġprivate Ġconst Ġval ĠBUILD _ CACHE _ CONTENT _ TYPE Ġ= Ġ" application / vnd . gradle . build - cache - artifact " ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġprivate Ġval Ġbuild Id Ġ= Ġ"% x ". format ( Random (). next Long ()) ĊĊĠĠĠ Ġprivate Ġval Ġcache Load s Ġ= ĠStop watch () ĊĠĠĠ Ġprivate Ġval Ġcache Load S avings Ġ= ĠStop watch () ĊĠĠĠ Ġprivate Ġval Ġcache Load W aste Ġ= ĠStop watch () ĊĠĠĠ Ġprivate Ġval Ġcache Hits Ġ= ĠStop watch () ĊĠĠĠ Ġprivate Ġval Ġcache Stores Ġ= ĠStop watch () ĊĊĠĠĠ Ġoverride Ġfun Ġclose () Ġ{ ĊĠĠĠĠĠĠĠ Ġfun ĠLong . byte Units () Ġ= Ġwhen Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġthis Ġ< Ġ 5 Ġ* Ġ 1 0 2 4 Ġ-> Ġ"${ this } ĠB " ĊĠĠĠĠĠĠĠĠĠĠĠ Ġthis Ġ< Ġ 5 Ġ* Ġ 1 0 2 4 Ġ* Ġ 1 2 0 4 Ġ-> Ġ"${ ( this Ġ+ Ġ 5 1 2 L ) Ġ/ Ġ( 1 0 2 4 L )} ĠK iB " ĊĠĠĠĠĠĠĠĠĠĠĠ Ġthis Ġ< Ġ 5 L Ġ* Ġ 1 0 2 4 Ġ* Ġ 1 2 0 4 Ġ* Ġ 1 0 2 4 Ġ-> Ġ"${ ( this Ġ+ Ġ 5 1 2 L Ġ* Ġ 1 0 2 4 ) Ġ/ Ġ( 1 0 2 4 L Ġ* Ġ 1 0 2 4 )} ĠM iB " ĊĠĠĠĠĠĠĠĠĠĠĠ Ġelse Ġ-> Ġ"${ ( this Ġ+ Ġ 5 1 2 L Ġ* Ġ 1 0 2 4 Ġ* Ġ 1 0 2 4 ) Ġ/ Ġ( 1 0 2 4 L Ġ* Ġ 1 0 2 4 Ġ* Ġ 1 0 2 4 )} ĠG iB " ĊĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠ Ġfun ĠLong . time Units () Ġ= Ġwhen Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġthis Ġ== Ġ 0 L Ġ-> Ġ" 0 s " ĊĠĠĠĠĠĠĠĠĠĠĠ Ġthis Ġ< Ġ 2 0 0 0 Ġ-> Ġ"${ this } ms " ĊĠĠĠĠĠĠĠĠĠĠĠ Ġthis Ġ< Ġ 1 2 0 Ġ* Ġ 1 0 0 0 Ġ-> Ġ"${ ( this Ġ+ Ġ 5 0 0 ) Ġ/ Ġ 1 0 0 0 } s " ĊĠĠĠĠĠĠĠĠĠĠĠ Ġelse Ġ-> Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġseconds Ġ= Ġ( this Ġ+ Ġ 5 0 0 ) Ġ/ Ġ 1 0 0 0 ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġminutes Ġ= Ġseconds Ġ/ Ġ 6 0 ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġhours Ġ= Ġminutes Ġ/ Ġ 6 0 ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( hours Ġ> Ġ 0 ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ"% 0 2 d :% 0 2 d :% 0 2 d ". format ( hours Ġ% Ġ 6 0 , Ġminutes Ġ% Ġ 6 0 , Ġseconds Ġ% Ġ 6 0 ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} Ġelse Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ"% 0 2 d :% 0 2 d ". format ( minutes Ġ% Ġ 6 0 , Ġseconds Ġ% Ġ 6 0 ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠ Ġfun ĠLong . saved W ast ed ( no Impact : ĠString Ġ= Ġ" no Ġimpact ") Ġ= Ġwhen Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġthis Ġ> Ġ 0 Ġ-> Ġ"${ time Units ()} Ġsaved " ĊĠĠĠĠĠĠĠĠĠĠĠ Ġthis Ġ< Ġ 0 Ġ-> Ġ"${ (- this ). time Units ()} Ġwast ed " ĊĠĠĠĠĠĠĠĠĠĠĠ Ġelse Ġ-> Ġno Impact ĊĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠ Ġs 3 . shutdown () ĊĊĠĠĠĠĠĠĠ Ġif Ġ(! show Statistics ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġreturn ĊĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠ Ġif Ġ( cache Load s . starts Ġ!= Ġ 0 ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġimpact Ġ= Ġcache Load S avings . elapsed Ġ- Ġcache Load W aste . elapsed ĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġsummary Ġ= Ġwhen Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġcache Load S avings . elapsed Ġ== Ġ 0 L Ġ&& Ġcache Load W aste . elapsed Ġ== Ġ 0 L Ġ-> ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ" no Ġimpact " ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġcache Load W aste . elapsed Ġ== Ġ 0 L Ġ-> ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ"${ cache Load S avings . elapsed . saved W ast ed ()} Ġon Ġhits " ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġcache Load S avings . elapsed Ġ== Ġ 0 L Ġ-> ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ"${ (- cache Load W aste . elapsed ). saved W ast ed ()} Ġon Ġmis ses " ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġelse Ġ-> ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ"${ impact . saved W ast ed ()} Ġ(${ cache Load S avings . elapsed . saved W ast ed ()} Ġon Ġhits , Ġ" Ġ+ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ"${ (- cache Load W aste . elapsed ). saved W ast ed ()} Ġon Ġmis ses )" ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġlogger . log ( ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( impact . absolute Value Ġ> Ġshow Statistics When Impact Ex ceeds Ġ|| ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġcache Load S avings . elapsed . absolute Value Ġ> Ġshow Statistics When S avings Ex ceeds Ġ|| ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġcache Load W aste . elapsed . absolute Value Ġ> Ġshow Statistics When W aste Ex ceeds Ġ|| ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġcache Load s . bytes Ġ> Ġshow Statistics When Transfer Ex ceeds ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ) ĠLogLevel . LI FE CYCLE Ġelse ĠLogLevel . INFO , ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ" S 3 Ġcache Ġ$ summary " Ġ+ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ( if Ġ( cache Load s . starts Ġ!= Ġcache Hits . starts ) Ġ", Ġreads : Ġ${ cache Load s . starts }" Ġelse Ġ"") Ġ+ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ( if Ġ( cache Hits . starts Ġ!= Ġ 0 ) Ġ", Ġhits : Ġ${ cache Hits . starts }" Ġelse Ġ"") Ġ+ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ( if Ġ( cache Load s . elapsed Ġ!= Ġ 0 L ) Ġ", Ġelapsed : Ġ${ cache Load s . elapsed . time Units () }" Ġelse Ġ"") Ġ+ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ( if Ġ( cache Load s . bytes Ġ!= Ġ 0 L ) Ġ", Ġprocessed : Ġ${ cache Load s . bytes . byte Units () }" Ġelse Ġ"") ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ) ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġif Ġ( cache Stores . starts Ġ!= Ġ 0 ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġlogger . lifecycle ( ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ" S 3 Ġcache Ġwrites : Ġ${ cache Stores . starts }, Ġ" Ġ+ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ" elapsed : Ġ${ cache Stores . elapsed . time Units ()}, Ġsent Ġto Ġcache : Ġ${ cache Stores . bytes . byte Units () }" ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ) ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġprivate Ġfun ĠBuild CacheKey . get Bucket Path () Ġ= Ġif Ġ( prefix . isNull OrEmpty ()) Ġ{ ĊĠĠĠĠĠĠĠ ĠhashCode ĊĠĠĠ Ġ} Ġelse Ġ{ ĊĠĠĠĠĠĠĠ Ġ"$ prefix $ hashCode " ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġoverride Ġfun Ġload ( key : ĠBuild CacheKey , Ġreader : ĠBuild Cache Entry Reader ): ĠBoolean Ġ{ ĊĠĠĠĠĠĠĠ Ġval Ġload Started Ġ= Ġcache Load s . elapsed ĊĊĠĠĠĠĠĠĠ Ġreturn Ġcache Load s Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġload Internal ( key , Ġreader ) ĊĠĠĠĠĠĠĠ Ġ}. apply Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ ĠCURRENT _ TASK . get ()?. let Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġit . cache Load Duration Ġ= Ġcache Load s . elapsed Ġ- Ġload Started ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġit . cache Load S avings Stop watch Ġ= Ġcache Load S avings ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġit . cache Load W aste Stop watch Ġ= Ġcache Load W aste ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġprivate Ġfun ĠStop watch . load Internal ( key : ĠBuild CacheKey , Ġreader : ĠBuild Cache Entry Reader ): ĠBoolean Ġ{ ĊĠĠĠĠĠĠĠ Ġval Ġbucket Path Ġ= Ġkey . get Bucket Path () ĊĠĠĠĠĠĠĠ Ġtry Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġlogger . info (" Loading Ġcache Ġentry Ġ'{}' Ġfrom ĠS 3 Ġbucket ", Ġbucket Path ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġs 3 . getObject ( bucketName , Ġbucket Path ). use Ġ{ Ġs 3 Object Ġ-> ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġcontent Length Ġ= Ġs 3 Object . object Metadata . content Length ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( content Length Ġ> Ġmaximum Cached Object Length ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġlogger . info ( ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ" Cache Ġitem Ġ'{}' Ġ'{}' Ġin ĠS 3 Ġbucket Ġsize Ġis Ġ{}, Ġand Ġit Ġexceeds Ġmaximum Cached Object Length Ġ{} . ĠWill Ġskip Ġthe Ġretrieval ", ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġkey , ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġbucket Path , ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġcontent Length , ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġmaximum Cached Object Length ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġreturn Ġfalse ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ// ĠPro pag ate Ġmetadata Ġso Ġtask Ġfinished Ġlistener Ġcan Ġcompute Ġtime Ġsaved / w ast ed ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠCURRENT _ TASK . get ()?. let Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġit . metadata Ġ= ĠCache Entry Metadata ( s 3 Object . object Metadata . user Metadata ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġbytes Processed ( content Length ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġcache Hits Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġreader . read From ( s 3 Object . object Content ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġreturn Ġtrue ĊĠĠĠĠĠĠĠ Ġ} Ġcatch Ġ( e : ĠAmazon S 3 Exception ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( e . statusCode Ġ== Ġ 4 0 3 Ġ|| Ġe . statusCode Ġ== Ġ 4 0 4 ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġlogger . info ( ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġwhen Ġ( e . statusCode ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ 4 0 3 Ġ-> Ġ" Got Ġ 4 0 3 Ġ( Forbidden ) Ġwhen Ġfetching Ġcache Ġitem Ġ'{}' Ġ'{}' Ġin ĠS 3 Ġbucket " ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġelse Ġ-> Ġ" Did Ġnot Ġfind Ġcache Ġitem Ġ'{}' Ġ'{}' Ġin ĠS 3 Ġbucket " ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ}, ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġkey , ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġbucket Path ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġreturn Ġfalse ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġlogger . info ( ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ" Unexpected Ġerror Ġwhen Ġfetching Ġcache Ġitem Ġ'{}' Ġ'{}' Ġin ĠS 3 Ġbucket ", ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġkey , ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġbucket Path , ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġe ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġreturn Ġfalse ; ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġoverride Ġfun Ġstore ( key : ĠBuild CacheKey , Ġwriter : ĠBuild Cache Entry Writer ) Ġ= Ġcache Stores Ġ{ ĊĠĠĠĠĠĠĠ Ġstore Internal ( key , Ġwriter ) ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġprivate Ġfun ĠStop watch . store Internal ( key : ĠBuild CacheKey , Ġwriter : ĠBuild Cache Entry Writer ) Ġ{ ĊĠĠĠĠĠĠĠ Ġval Ġbucket Path Ġ= Ġkey . get Bucket Path () ĊĠĠĠĠĠĠĠ Ġval Ġitem Size Ġ= Ġwriter . size ĊĠĠĠĠĠĠĠ Ġif Ġ( item Size Ġ> Ġmaximum Cached Object Length ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġlogger . info ( ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ" Cache Ġitem Ġ'{}' Ġ'{}' Ġin ĠS 3 Ġbucket Ġsize Ġis Ġ{}, Ġand Ġit Ġexceeds Ġmaximum Cached Object Length Ġ{} . ĠWill Ġskip Ġcaching Ġit .", ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġkey , ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġbucket Path , ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġitem Size , ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġmaximum Cached Object Length ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġreturn ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġbytes Processed ( item Size ) ĊĠĠĠĠĠĠĠ Ġlogger . info (" St oring Ġcache Ġentry Ġ'{}' Ġto ĠS 3 Ġbucket ", Ġbucket Path ) ĊĠĠĠĠĠĠĠ Ġval Ġmeta Ġ= ĠObject Metadata (). apply Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ ĠcontentType Ġ= ĠBUILD _ CACHE _ CONTENT _ TYPE ĊĠĠĠĠĠĠĠĠĠĠĠ Ġcontent Length Ġ= Ġwriter . size ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġval Ġmetadata Ġ= Ġwriter . read Build Metadata () Ġ?: ĠCURRENT _ TASK . get ()?. let Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ ĠCache Entry Metadata ( ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġbuild Invocation Id Ġ= Ġbuild Id , ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġidentity Ġ= Ġit . path , ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġexecution Time Ġ= ĠSystem . currentTimeMillis () Ġ- Ġit . execution Started , ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġoperating System Ġ= ĠSystem . getProperty (" os . name "), ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġgradle Version Ġ= ĠGradle Version . current (). toString () ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ) ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġmetadata ?. appendTo ( meta . user Metadata ) ĊĠĠĠĠĠĠĠ Ġtry Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġrequest Ġ= Ġwriter . file ()?. let Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ// ĠIf Ġfile Ġis Ġaval iable , Ġuse Ġit Ġdirectly ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠPut Object Request ( bucketName , Ġbucket Path , Ġit ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} Ġ?: ĠPut Object Request ( ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġbucket Name , Ġbucket Path , ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠByteArrayInputStream ( ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠByteArrayOutputStream () ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ. also Ġ{ Ġos Ġ-> Ġwriter . writeTo ( os ) Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ. toByteArray () ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ), Ġmeta ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġrequest . metadata Ġ= Ġmeta ĊĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( reduced Red undancy ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġrequest . with Storage Class ( Storage Class . Reduc ed Red undancy ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġs 3 . put Object ( request ) ĊĠĠĠĠĠĠĠ Ġ} Ġcatch Ġ( e : ĠIOException ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġthrow ĠBuild Cache Exception (" Error Ġwhile Ġstoring Ġcache Ġobject Ġin ĠS 3 Ġbucket ", Ġe ) ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} Ċ } Ċ