Received: from malur.postgresql.org ([217.196.149.56]) by arkaria.postgresql.org with esmtps (TLS1.3) tls TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 (Exim 4.94.2) (envelope-from ) id 1sjrc0-004vf9-Ah for pgsql-hackers@arkaria.postgresql.org; Fri, 30 Aug 2024 02:43:44 +0000 Received: from localhost ([127.0.0.1] helo=malur.postgresql.org) by malur.postgresql.org with esmtp (Exim 4.94.2) (envelope-from ) id 1sjrby-00CNVs-AR for pgsql-hackers@arkaria.postgresql.org; Fri, 30 Aug 2024 02:43:42 +0000 Received: from magus.postgresql.org ([2a02:c0:301:0:ffff::29]) by malur.postgresql.org with esmtps (TLS1.3) tls TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 (Exim 4.94.2) (envelope-from ) id 1sjrbx-00CNVb-Ru for pgsql-hackers@lists.postgresql.org; Fri, 30 Aug 2024 02:43:42 +0000 Received: from mail-lj1-x22e.google.com ([2a00:1450:4864:20::22e]) by magus.postgresql.org with esmtps (TLS1.3) tls TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256 (Exim 4.94.2) (envelope-from ) id 1sjrbu-002BFd-G9 for pgsql-hackers@lists.postgresql.org; Fri, 30 Aug 2024 02:43:41 +0000 Received: by mail-lj1-x22e.google.com with SMTP id 38308e7fff4ca-2f3e071eb64so16991231fa.1 for ; Thu, 29 Aug 2024 19:43:39 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20230601; t=1724985818; x=1725590618; darn=lists.postgresql.org; h=cc:to:subject:message-id:date:from:in-reply-to:references :mime-version:from:to:cc:subject:date:message-id:reply-to; bh=L6rQ3HKUiyKzl3aU1jjdqjo9OBxuMutIwnPx9n72JwI=; b=CDokRS1HAQ7MynpM4/GjqAu55aCuDdF7t4gHAbZQbTqIccmZvAHS3d9v0DQXywllgU s4Qcc1czVfK5gcqfat4D9p/qEfxTGSr3LFxUecVe2f9jwJcH5A4phyNmE0jv/B9beN8c IBiDsRvP4tjWa8B/ZrNch9yz3ZFnoEOpxNmbhgPccPQT9ew387QblZkIsCDEaaJgCExU cxpqnWXLxqI3KSmPxuDbjPBYalPs/MSsI/EHSbcFF+lGFT8W/sEVNHuC0OFdQkqR2JmW BYzf4c1WIniKizJMbldJWGUqoPObVbJM4YvLfSF2QijDvgL/5dy9ETizhl1xeP7jTGBo bEPw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1724985818; x=1725590618; h=cc:to:subject:message-id:date:from:in-reply-to:references :mime-version:x-gm-message-state:from:to:cc:subject:date:message-id :reply-to; bh=L6rQ3HKUiyKzl3aU1jjdqjo9OBxuMutIwnPx9n72JwI=; b=Km7EW8h8p7VFiYhzZ6D6k/TwnsJJ/Ved+j4Kn6hnz5fEcxyajHrmHg9Cjf25eQd4Gy /pNVMg5gkGQtc5/dcaM2qY6+vhYFKT7eyq/op2XJHzsNVJUo09rz/w0wVAjA3gf+JzGL objk3GHjHkNyZPInRcAcJpttww0eplt8Ro2Oi73rI2i9mUPAZhckpWln0X/uFEg+bVFq u3bzLaIFEQLQyS7WOLed8G6JGerlfCZHtoBRTHgXdfq8Y9y4ggzptvjhX7Nanv7Ijl+a f80HAb+DJIw/cYLtZoyD44O91o0u2uXh/xRBe2J0In2EoX4OfsyqIDUOqsv6AipLgHjP C1MQ== X-Forwarded-Encrypted: i=1; AJvYcCWb7kJwE3u/Iiqs413OAfD1sxl1UDbxl1pFitibsgPxkOphuLy3gd4jPjWDim3jBSTyQbNJeuSovi5rBns5@lists.postgresql.org X-Gm-Message-State: AOJu0YwUvjQvaKsPivDDHP0ouYsjbY1C2lJuRMuEmpTzULOBol+TJad6 6oZ2uOIXS+U77PB0aNm+pmZDD+4Embyi7phGpsQCNqNtWENB/feKBMQR1IcCgTVMEyoyyYZ3rVn tznLUJaMQ3U1sySvVhiYboRKB/8tNng/5 X-Google-Smtp-Source: AGHT+IFSqM76uo/I2E9YAmAZxMOISyKyuVMXKgl3EYQzFtAZRKlmL6jOJ0YtbfQBjdVLCWNX7dYP8pQQRWLUAiYk3oM= X-Received: by 2002:a2e:a987:0:b0:2ef:226e:e150 with SMTP id 38308e7fff4ca-2f6108930d5mr43897121fa.32.1724985817680; Thu, 29 Aug 2024 19:43:37 -0700 (PDT) MIME-Version: 1.0 References: In-Reply-To: From: Peter Smith Date: Fri, 30 Aug 2024 12:43:10 +1000 Message-ID: Subject: Re: Introduce XID age and inactive timeout based replication slot invalidation To: Bharath Rupireddy Cc: Amit Kapila , Ajin Cherian , Bertrand Drouvot , shveta malik , Masahiko Sawada , Nathan Bossart , PostgreSQL Hackers Content-Type: multipart/mixed; boundary="000000000000e7ec690620dd8e54" List-Id: List-Help: List-Subscribe: List-Post: List-Owner: List-Archive: Archived-At: Precedence: bulk --000000000000e7ec690620dd8e54 Content-Type: text/plain; charset="UTF-8" Hi, here are some review comments for patch v43-0001. ====== Commit message 1. ... introduces a GUC allowing users set inactive timeout. ~ 1a. You should give the name of the new GUC in the commit message. 1b. /set/to set/ ====== doc/src/sgml/config.sgml GUC "replication_slot_inactive_timeout" 2. Invalidates replication slots that are inactive for longer than specified amount of time nit - suggest use similar wording as the prior GUC (wal_sender_timeout): Invalidate replication slots that are inactive for longer than this amount of time. ~ 3. This invalidation check happens either when the slot is acquired for use or during a checkpoint. The time since the slot has become inactive is known from its inactive_since value using which the timeout is measured. nit - the wording is too complicated. suggest: The timeout check occurs when the slot is next acquired for use, or during a checkpoint. The slot's 'inactive_since' field value is when the slot became inactive. ~ 4. Note that the inactive timeout invalidation mechanism is not applicable for slots on the standby that are being synced from a primary server (whose synced field is true). nit - that word "whose" seems ambiguous. suggest: (e.g. the standby slot has 'synced' field true). ====== doc/src/sgml/system-views.sgml 5. inactive_timeout means that the slot has been inactive for the duration specified by replication_slot_inactive_timeout parameter. nit - suggestion ("longer than"): ... the slot has been inactive for longer than the duration specified by the replication_slot_inactive_timeout parameter. ====== src/backend/replication/slot.c 6. /* Maximum number of invalidation causes */ -#define RS_INVAL_MAX_CAUSES RS_INVAL_WAL_LEVEL +#define RS_INVAL_MAX_CAUSES RS_INVAL_INACTIVE_TIMEOUT IMO this #define belongs in the slot.h, immediately below where the enum is defined. ~~~ 7. ReplicationSlotAcquire: I had a fundamental question about this logic. IIUC the purpose of the patch was to invalidate replication slots that have been inactive for too long. So, it makes sense to me that some periodic processing (e.g. CheckPointReplicationSlots) might do a sweep over all the slots, and invalidate the too-long-inactive ones that it finds. OTOH, it seemed quite strange to me that the patch logic is also detecting and invalidating inactive slots during the ReplicationSlotAcquire function. This is kind of saying "ERROR - sorry, because this was inactive for too long you can't have it" at the very moment that you wanted to use it again! IIUC such a slot would be invalidated by the function InvalidatePossiblyObsoleteSlot(), but therein lies my doubt -- how can the slot be considered as "obsolete" when we are in the very act of trying to acquire/use it? I guess it might be argued this is not so different to the scenario of attempting to acquire a slot that had been invalidated momentarily before during checkpoint processing. But, somehow that scenario seems more like bad luck to me, versus ReplicationSlotAcquire() deliberately invalidating something we *know* is wanted. ~ 8. + ereport(ERROR, + (errcode(ERRCODE_OBJECT_NOT_IN_PREREQUISITE_STATE), + errmsg("can no longer get changes from replication slot \"%s\"", + NameStr(s->data.name)), + errdetail("This slot has been invalidated because it was inactive since %s for more than %d seconds specified by \"replication_slot_inactive_timeout\".", + timestamptz_to_str(s->inactive_since), + replication_slot_inactive_timeout))); nit - IMO the info should be split into errdetail + errhint. Like this: errdetail("The slot became invalid because it was inactive since %s, which is more than %d seconds ago."...) errhint("You might need to increase \"%s\".", "replication_slot_inactive_timeout") ~~~ 9. ReportSlotInvalidation + appendStringInfo(&err_detail, + _("The slot has been inactive since %s for more than %d seconds specified by \"replication_slot_inactive_timeout\"."), + timestamptz_to_str(inactive_since), + replication_slot_inactive_timeout); + break; IMO this error in ReportSlotInvalidation() should be the same as the other one from ReplicationSlotAcquire(), which I suggested above (comment #8) should include a hint. Also, including a hint here will make this new message consistent with the other errhint (for "max_slot_wal_keep_size") that is already in this function. ~~~ 10. InvalidatePossiblyObsoleteSlot + if (cause == RS_INVAL_INACTIVE_TIMEOUT && + (replication_slot_inactive_timeout > 0 && + s->inactive_since > 0 && + !(RecoveryInProgress() && s->data.synced))) 10a. Everything here is && so this has some redundant parentheses. 10b. Actually, IMO this complicated condition is overkill. Won't it be better to just unconditionally assign now = GetCurrentTimestamp(); here? ~ 11. + * Note that we don't invalidate synced slots because, + * they are typically considered not active as they don't + * perform logical decoding to produce the changes. nit - tweaked punctuation ~ 12. + * If the slot can be acquired, do so or if the slot is already ours, + * then mark it invalidated. Otherwise we'll signal the owning + * process, below, and retry. nit - tidied this comment. Suggestion: If the slot can be acquired, do so and mark it as invalidated. If the slot is already ours, mark it as invalidated. Otherwise, we'll signal the owning process below and retry. ~ 13. + if (active_pid == 0 || + (MyReplicationSlot != NULL && + MyReplicationSlot == s && + active_pid == MyProcPid)) You are already checking MyReplicationSlot == s here, so that extra check for MyReplicationSlot != NULL is redundant, isn't it? ~~~ 14. CheckPointReplicationSlots /* - * Flush all replication slots to disk. + * Flush all replication slots to disk. Also, invalidate slots during + * non-shutdown checkpoint. * * It is convenient to flush dirty replication slots at the time of checkpoint. * Additionally, in case of a shutdown checkpoint, we also identify the slots nit - /Also, invalidate slots/Also, invalidate obsolete slots/ ====== src/backend/utils/misc/guc_tables.c 15. + {"replication_slot_inactive_timeout", PGC_SIGHUP, REPLICATION_SENDING, + gettext_noop("Sets the amount of time to wait before invalidating an " + "inactive replication slot."), nit - that is maybe a bit misleading because IIUC there is no real "waiting" happening anywhere. Suggest: Sets the amount of time a replication slot can remain inactive before it will be invalidated. ====== Please take a look at the attached top-up patches. These include changes for many of the nits above. ====== Kind Regards, Peter Smith. Fujitsu Australia --000000000000e7ec690620dd8e54 Content-Type: text/plain; charset="US-ASCII"; name="PS_NITPICKS_20240830_CODE_V430001.txt" Content-Disposition: attachment; filename="PS_NITPICKS_20240830_CODE_V430001.txt" Content-Transfer-Encoding: base64 Content-ID: X-Attachment-Id: f_m0g3qrik1 ZGlmZiAtLWdpdCBhL3NyYy9iYWNrZW5kL3JlcGxpY2F0aW9uL3Nsb3QuYyBiL3NyYy9iYWNrZW5k L3JlcGxpY2F0aW9uL3Nsb3QuYwppbmRleCA3MDA5MzUwLi5jOTZhZTUzIDEwMDY0NAotLS0gYS9z cmMvYmFja2VuZC9yZXBsaWNhdGlvbi9zbG90LmMKKysrIGIvc3JjL2JhY2tlbmQvcmVwbGljYXRp b24vc2xvdC5jCkBAIC02NzEsOSArNjcxLDEwIEBAIHJldHJ5OgogCQkJCQkoZXJyY29kZShFUlJD T0RFX09CSkVDVF9OT1RfSU5fUFJFUkVRVUlTSVRFX1NUQVRFKSwKIAkJCQkJIGVycm1zZygiY2Fu IG5vIGxvbmdlciBnZXQgY2hhbmdlcyBmcm9tIHJlcGxpY2F0aW9uIHNsb3QgXCIlc1wiIiwKIAkJ CQkJCQlOYW1lU3RyKHMtPmRhdGEubmFtZSkpLAotCQkJCQkgZXJyZGV0YWlsKCJUaGlzIHNsb3Qg aGFzIGJlZW4gaW52YWxpZGF0ZWQgYmVjYXVzZSBpdCB3YXMgaW5hY3RpdmUgc2luY2UgJXMgZm9y IG1vcmUgdGhhbiAlZCBzZWNvbmRzIHNwZWNpZmllZCBieSBcInJlcGxpY2F0aW9uX3Nsb3RfaW5h Y3RpdmVfdGltZW91dFwiLiIsCisJCQkJCSBlcnJkZXRhaWwoIlRoZSBzbG90IGJlY2FtZSBpbnZh bGlkIGJlY2F1c2UgaXQgd2FzIGluYWN0aXZlIHNpbmNlICVzLCB3aGljaCBpcyBtb3JlIHRoYW4g JWQgc2Vjb25kcyBhZ28uIiwKIAkJCQkJCQkgICB0aW1lc3RhbXB0el90b19zdHIocy0+aW5hY3Rp dmVfc2luY2UpLAotCQkJCQkJCSAgIHJlcGxpY2F0aW9uX3Nsb3RfaW5hY3RpdmVfdGltZW91dCkp KTsKKwkJCQkJCQkgICByZXBsaWNhdGlvbl9zbG90X2luYWN0aXZlX3RpbWVvdXQpLAorCQkJCQkg ZXJyaGludCgiWW91IG1pZ2h0IG5lZWQgdG8gaW5jcmVhc2UgXCIlc1wiLiIsICJyZXBsaWNhdGlv bl9zbG90X2luYWN0aXZlX3RpbWVvdXQiKSkpOwogCQl9CiAJfQogCkBAIC0xNzM4LDkgKzE3Mzks OSBAQCBJbnZhbGlkYXRlUG9zc2libHlPYnNvbGV0ZVNsb3QoUmVwbGljYXRpb25TbG90SW52YWxp ZGF0aW9uQ2F1c2UgY2F1c2UsCiAJCQkJCSAqIGlzIGRpc2FibGVkIG9yIHNsb3QgaXMgY3VycmVu dGx5IGJlaW5nIHVzZWQgb3IgdGhlIHNsb3QKIAkJCQkJICogb24gc3RhbmRieSBpcyBjdXJyZW50 bHkgYmVpbmcgc3luY2VkIGZyb20gdGhlIHByaW1hcnkuCiAJCQkJCSAqCi0JCQkJCSAqIE5vdGUg dGhhdCB3ZSBkb24ndCBpbnZhbGlkYXRlIHN5bmNlZCBzbG90cyBiZWNhdXNlLAotCQkJCQkgKiB0 aGV5IGFyZSB0eXBpY2FsbHkgY29uc2lkZXJlZCBub3QgYWN0aXZlIGFzIHRoZXkgZG9uJ3QKLQkJ CQkJICogcGVyZm9ybSBsb2dpY2FsIGRlY29kaW5nIHRvIHByb2R1Y2UgdGhlIGNoYW5nZXMuCisJ CQkJCSAqIE5vdGUgdGhhdCB3ZSBkb24ndCBpbnZhbGlkYXRlIHN5bmNlZCBzbG90cyBiZWNhdXNl CisJCQkJCSAqIHRoZXkgYXJlIHR5cGljYWxseSBjb25zaWRlcmVkIG5vdCBhY3RpdmUsIGFzIHRo ZXkgZG9uJ3QKKwkJCQkJICogcGVyZm9ybSBsb2dpY2FsIGRlY29kaW5nIHRvIHByb2R1Y2UgY2hh bmdlcy4KIAkJCQkJICovCiAJCQkJCWlmIChyZXBsaWNhdGlvbl9zbG90X2luYWN0aXZlX3RpbWVv dXQgPT0gMCB8fAogCQkJCQkJcy0+aW5hY3RpdmVfc2luY2UgPT0gMCB8fApAQCAtMTc4OSw5ICsx NzkwLDkgQEAgSW52YWxpZGF0ZVBvc3NpYmx5T2Jzb2xldGVTbG90KFJlcGxpY2F0aW9uU2xvdElu dmFsaWRhdGlvbkNhdXNlIGNhdXNlLAogCQlhY3RpdmVfcGlkID0gcy0+YWN0aXZlX3BpZDsKIAog CQkvKgotCQkgKiBJZiB0aGUgc2xvdCBjYW4gYmUgYWNxdWlyZWQsIGRvIHNvIG9yIGlmIHRoZSBz bG90IGlzIGFscmVhZHkgb3VycywKLQkJICogdGhlbiBtYXJrIGl0IGludmFsaWRhdGVkLiAgT3Ro ZXJ3aXNlIHdlJ2xsIHNpZ25hbCB0aGUgb3duaW5nCi0JCSAqIHByb2Nlc3MsIGJlbG93LCBhbmQg cmV0cnkuCisJCSAqIElmIHRoZSBzbG90IGNhbiBiZSBhY3F1aXJlZCwgZG8gc28gYW5kIG1hcmsg aXQgYXMgaW52YWxpZGF0ZWQuCisJCSAqIElmIHRoZSBzbG90IGlzIGFscmVhZHkgb3VycywgbWFy ayBpdCBhcyBpbnZhbGlkYXRlZC4KKwkJICogT3RoZXJ3aXNlLCB3ZSdsbCBzaWduYWwgdGhlIG93 bmluZyBwcm9jZXNzIGJlbG93IGFuZCByZXRyeS4KIAkJICovCiAJCWlmIChhY3RpdmVfcGlkID09 IDAgfHwKIAkJCShNeVJlcGxpY2F0aW9uU2xvdCAhPSBOVUxMICYmCkBAIC0xOTc1LDcgKzE5NzYs NyBAQCByZXN0YXJ0OgogfQogCiAvKgotICogRmx1c2ggYWxsIHJlcGxpY2F0aW9uIHNsb3RzIHRv IGRpc2suIEFsc28sIGludmFsaWRhdGUgc2xvdHMgZHVyaW5nCisgKiBGbHVzaCBhbGwgcmVwbGlj YXRpb24gc2xvdHMgdG8gZGlzay4gQWxzbywgaW52YWxpZGF0ZSBvYnNvbGV0ZSBzbG90cyBkdXJp bmcKICAqIG5vbi1zaHV0ZG93biBjaGVja3BvaW50LgogICoKICAqIEl0IGlzIGNvbnZlbmllbnQg dG8gZmx1c2ggZGlydHkgcmVwbGljYXRpb24gc2xvdHMgYXQgdGhlIHRpbWUgb2YgY2hlY2twb2lu dC4KZGlmZiAtLWdpdCBhL3NyYy9iYWNrZW5kL3V0aWxzL21pc2MvZ3VjX3RhYmxlcy5jIGIvc3Jj L2JhY2tlbmQvdXRpbHMvbWlzYy9ndWNfdGFibGVzLmMKaW5kZXggODYxNjkyYy4uNzNhNTgyNCAx MDA2NDQKLS0tIGEvc3JjL2JhY2tlbmQvdXRpbHMvbWlzYy9ndWNfdGFibGVzLmMKKysrIGIvc3Jj L2JhY2tlbmQvdXRpbHMvbWlzYy9ndWNfdGFibGVzLmMKQEAgLTMwMzAsOCArMzAzMCw5IEBAIHN0 cnVjdCBjb25maWdfaW50IENvbmZpZ3VyZU5hbWVzSW50W10gPQogCiAJewogCQl7InJlcGxpY2F0 aW9uX3Nsb3RfaW5hY3RpdmVfdGltZW91dCIsIFBHQ19TSUdIVVAsIFJFUExJQ0FUSU9OX1NFTkRJ TkcsCi0JCQlnZXR0ZXh0X25vb3AoIlNldHMgdGhlIGFtb3VudCBvZiB0aW1lIHRvIHdhaXQgYmVm b3JlIGludmFsaWRhdGluZyBhbiAiCi0JCQkJCQkgImluYWN0aXZlIHJlcGxpY2F0aW9uIHNsb3Qu IiksCisKKwkJCWdldHRleHRfbm9vcCgiU2V0cyB0aGUgYW1vdW50IG9mIHRpbWUgYSByZXBsaWNh dGlvbiBzbG90IGNhbiByZW1haW4gIgorCQkJCQkJICJpbmFjdGl2ZSBiZWZvcmUgaXQgd2lsbCBi ZSBpbnZhbGlkYXRlZC4iKSwKIAkJCU5VTEwsCiAJCQlHVUNfVU5JVF9TCiAJCX0sCg== --000000000000e7ec690620dd8e54 Content-Type: text/plain; charset="US-ASCII"; name="PS_NITPICKS_20240829_DOCS_v430001.txt" Content-Disposition: attachment; filename="PS_NITPICKS_20240829_DOCS_v430001.txt" Content-Transfer-Encoding: base64 Content-ID: X-Attachment-Id: f_m0g3qrhv0 ZGlmZiAtLWdpdCBhL2RvYy9zcmMvc2dtbC9jb25maWcuc2dtbCBiL2RvYy9zcmMvc2dtbC9jb25m aWcuc2dtbAppbmRleCBmYmJhY2JlLi5iZDNjZTVhIDEwMDY0NAotLS0gYS9kb2Mvc3JjL3NnbWwv Y29uZmlnLnNnbWwKKysrIGIvZG9jL3NyYy9zZ21sL2NvbmZpZy5zZ21sCkBAIC00NTY4LDggKzQ1 NjgsOCBAQCByZXN0b3JlX2NvbW1hbmQgPSAnY29weSAiQzpcXHNlcnZlclxcYXJjaGl2ZWRpclxc JWYiICIlcCInICAjIFdpbmRvd3MKICAgICAgIDwvdGVybT4KICAgICAgIDxsaXN0aXRlbT4KICAg ICAgICA8cGFyYT4KLSAgICAgICAgSW52YWxpZGF0ZXMgcmVwbGljYXRpb24gc2xvdHMgdGhhdCBh cmUgaW5hY3RpdmUgZm9yIGxvbmdlciB0aGFuCi0gICAgICAgIHNwZWNpZmllZCBhbW91bnQgb2Yg dGltZS4gSWYgdGhpcyB2YWx1ZSBpcyBzcGVjaWZpZWQgd2l0aG91dCB1bml0cywKKyAgICAgICAg SW52YWxpZGF0ZSByZXBsaWNhdGlvbiBzbG90cyB0aGF0IGFyZSBpbmFjdGl2ZSBmb3IgbG9uZ2Vy IHRoYW4gdGhpcworICAgICAgICBhbW91bnQgb2YgdGltZS4gSWYgdGhpcyB2YWx1ZSBpcyBzcGVj aWZpZWQgd2l0aG91dCB1bml0cywKICAgICAgICAgaXQgaXMgdGFrZW4gYXMgc2Vjb25kcy4gQSB2 YWx1ZSBvZiB6ZXJvICh3aGljaCBpcyBkZWZhdWx0KSBkaXNhYmxlcwogICAgICAgICB0aGUgdGlt ZW91dCBtZWNoYW5pc20uIFRoaXMgcGFyYW1ldGVyIGNhbiBvbmx5IGJlIHNldCBpbgogICAgICAg ICB0aGUgPGZpbGVuYW1lPnBvc3RncmVzcWwuY29uZjwvZmlsZW5hbWU+IGZpbGUgb3Igb24gdGhl IHNlcnZlcgpAQCAtNDU3NywxOCArNDU3NywxNiBAQCByZXN0b3JlX2NvbW1hbmQgPSAnY29weSAi QzpcXHNlcnZlclxcYXJjaGl2ZWRpclxcJWYiICIlcCInICAjIFdpbmRvd3MKICAgICAgICA8L3Bh cmE+CiAKICAgICAgICA8cGFyYT4KLSAgICAgICAgVGhpcyBpbnZhbGlkYXRpb24gY2hlY2sgaGFw cGVucyBlaXRoZXIgd2hlbiB0aGUgc2xvdCBpcyBhY3F1aXJlZAotICAgICAgICBmb3IgdXNlIG9y IGR1cmluZyBhIGNoZWNrcG9pbnQuIFRoZSB0aW1lIHNpbmNlIHRoZSBzbG90IGhhcyBiZWNvbWUK LSAgICAgICAgaW5hY3RpdmUgaXMga25vd24gZnJvbSBpdHMKLSAgICAgICAgPHN0cnVjdGZpZWxk PmluYWN0aXZlX3NpbmNlPC9zdHJ1Y3RmaWVsZD4gdmFsdWUgdXNpbmcgd2hpY2ggdGhlCi0gICAg ICAgIHRpbWVvdXQgaXMgbWVhc3VyZWQuCisgICAgICAgIFRoZSB0aW1lb3V0IGNoZWNrIG9jY3Vy cyB3aGVuIHRoZSBzbG90IGlzIG5leHQgYWNxdWlyZWQgZm9yIHVzZSwgb3IKKyAgICAgICAgZHVy aW5nIGEgY2hlY2twb2ludC4gVGhlIHNsb3QncyA8c3RydWN0ZmllbGQ+aW5hY3RpdmVfc2luY2U8 L3N0cnVjdGZpZWxkPgorICAgICAgICBmaWVsZCB2YWx1ZSBpcyB3aGVuIHRoZSBzbG90IGJlY2Ft ZSBpbmFjdGl2ZS4KICAgICAgICA8L3BhcmE+CiAKICAgICAgICA8cGFyYT4KICAgICAgICAgTm90 ZSB0aGF0IHRoZSBpbmFjdGl2ZSB0aW1lb3V0IGludmFsaWRhdGlvbiBtZWNoYW5pc20gaXMgbm90 CiAgICAgICAgIGFwcGxpY2FibGUgZm9yIHNsb3RzIG9uIHRoZSBzdGFuZGJ5IHRoYXQgYXJlIGJl aW5nIHN5bmNlZCBmcm9tIGEKLSAgICAgICAgcHJpbWFyeSBzZXJ2ZXIgKHdob3NlIDxzdHJ1Y3Rm aWVsZD5zeW5jZWQ8L3N0cnVjdGZpZWxkPiBmaWVsZCBpcwotICAgICAgICA8bGl0ZXJhbD50cnVl PC9saXRlcmFsPikuCisgICAgICAgIHByaW1hcnkgc2VydmVyIChlLmcuIHRoZSBzdGFuZGJ5IHNs b3QgPHN0cnVjdGZpZWxkPnN5bmNlZDwvc3RydWN0ZmllbGQ+CisgICAgICAgIGZpZWxkIGlzIHRy dWUpLgogICAgICAgIDwvcGFyYT4KICAgICAgIDwvbGlzdGl0ZW0+CiAgICAgIDwvdmFybGlzdGVu dHJ5PgpkaWZmIC0tZ2l0IGEvZG9jL3NyYy9zZ21sL3N5c3RlbS12aWV3cy5zZ21sIGIvZG9jL3Ny Yy9zZ21sL3N5c3RlbS12aWV3cy5zZ21sCmluZGV4IDllMDBmN2QuLmYyMzBlNmUgMTAwNjQ0Ci0t LSBhL2RvYy9zcmMvc2dtbC9zeXN0ZW0tdmlld3Muc2dtbAorKysgYi9kb2Mvc3JjL3NnbWwvc3lz dGVtLXZpZXdzLnNnbWwKQEAgLTI2MjEsNyArMjYyMSw3IEBAIFNFTEVDVCAqIEZST00gcGdfbG9j a3MgcGwgTEVGVCBKT0lOIHBnX3ByZXBhcmVkX3hhY3RzIHBweAogICAgICAgICA8bGlzdGl0ZW0+ CiAgICAgICAgICA8cGFyYT4KICAgICAgICAgICA8bGl0ZXJhbD5pbmFjdGl2ZV90aW1lb3V0PC9s aXRlcmFsPiBtZWFucyB0aGF0IHRoZSBzbG90IGhhcyBiZWVuCi0gICAgICAgICAgaW5hY3RpdmUg Zm9yIHRoZSBkdXJhdGlvbiBzcGVjaWZpZWQgYnkKKyAgICAgICAgICBpbmFjdGl2ZSBmb3IgbG9u Z2VyIHRoYW4gdGhlIGR1cmF0aW9uIHNwZWNpZmllZCBieQogICAgICAgICAgIDx4cmVmIGxpbmtl bmQ9Imd1Yy1yZXBsaWNhdGlvbi1zbG90LWluYWN0aXZlLXRpbWVvdXQiLz4gcGFyYW1ldGVyLgog ICAgICAgICAgPC9wYXJhPgogICAgICAgICA8L2xpc3RpdGVtPgo= --000000000000e7ec690620dd8e54--