From daf896e117f9dd033d161f5b4f600d221e7cfb0b Mon Sep 17 00:00:00 2001 From: Correl Roush Date: Tue, 12 Apr 2022 14:28:42 -0400 Subject: [PATCH] updates --- ...210914142000-subscriber_search_service.org | 4 + ...15-null_and_postgresql_array_operators.org | 136 +++++++++++ daily/2022-03-22.org | 127 ++++++++++ .../2022-03-29-accounts-with-invalid-tags.png | Bin 0 -> 14637 bytes daily/2022-03-29-invalid-tag-breakdown.png | Bin 0 -> 41936 bytes ...22-03-29-subscribers-with-invalid-tags.png | Bin 0 -> 13927 bytes daily/2022-03-29.org | 216 +++++++++++++++--- daily/2022-04-06.org | 27 +++ daily/2022-04-07.org | 92 ++++++++ daily/2022-04-12.org | 144 ++++++++++++ 10 files changed, 710 insertions(+), 36 deletions(-) create mode 100644 aweber/20220407112615-null_and_postgresql_array_operators.org create mode 100644 daily/2022-03-29-accounts-with-invalid-tags.png create mode 100644 daily/2022-03-29-invalid-tag-breakdown.png create mode 100644 daily/2022-03-29-subscribers-with-invalid-tags.png create mode 100644 daily/2022-04-06.org create mode 100644 daily/2022-04-07.org create mode 100644 daily/2022-04-12.org diff --git a/aweber/20210914142000-subscriber_search_service.org b/aweber/20210914142000-subscriber_search_service.org index 64a0468..c09b84a 100644 --- a/aweber/20210914142000-subscriber_search_service.org +++ b/aweber/20210914142000-subscriber_search_service.org @@ -62,6 +62,10 @@ Added: [2019-08-06 Tue 10:34] * Concerns ** Performance +Email delivery has cases + +*** Analytics query speedups for broadcasts +https://jira.aweber.io/browse/EDELIV-8318 ** Fitness to Purpose This service will need to fulfill the needs of both end-user subscriber searches and segment emailing. diff --git a/aweber/20220407112615-null_and_postgresql_array_operators.org b/aweber/20220407112615-null_and_postgresql_array_operators.org new file mode 100644 index 0000000..96d9b80 --- /dev/null +++ b/aweber/20220407112615-null_and_postgresql_array_operators.org @@ -0,0 +1,136 @@ +:PROPERTIES: +:ID: 00cf1628-bc60-451d-bd30-d11d6b92992f +:header-args:sql: :engine postgresql :cmdline "-U postgres postgres" :dir /docker:postgres: :exports both :cache yes :eval no-export +:END: +#+title: Null and PostgreSQL array operators + +Researching an issue in subscriber search and broadcast sending resulted in +learning some interesting things about [[id:af84ed59-96a4-4f9c-b34c-b79178ad20cb][PostgreSQL]]'s generation and handling of +=NULL= values, despite its otherwise strict type checking. + +* The symptom +[[https://jira.aweber.io/browse/ASE-8617][ASE-8617]] describes a scenario where a customer ([[https://admin.aweber.io/account/index/1018872][AID 1018872]]) sends broadcasts to +a segment ("no tags subscribers") on their list (List ID 5830776), defined with +the following criteria: + +#+caption: Segment definition: "no tags subscribers" +| Tag | is not | wr | +| Tag | is not | cb | +| Tag | is not | cb2 | +| Tag | is not | fsc | +| Tag | is not | flp | +| Tag | is not | lsa | + +Normally, they expect this segment to reach >1000 subscribers. Following a +release of our [[id:d06d3ab4-c2d0-47c3-aae1-4395567fc3d2][Tag Normalization]] changes, they sent a broadcast to this segment +that only reached 7 subscribers. Rolling back the [[https://gitlab.aweber.io/DBA/ddl/schema-deploy/-/merge_requests/257][change to segment search terms]] +corrected the issue for the customer. + +* The implementation + +** The "Tag Is Not" search filter +The change updated the tag "is not" filter from +#+begin_src sql :exports code :eval never + (NOT(tags @> ARRAY[=:$1:=]) or tags is null) +#+end_src +to +#+begin_src sql :exports code :eval never + (NOT(public.normalize_tags(tags) @> public.normalize_tags(ARRAY[=:$1:=])) or tags is null) +#+end_src +** The =normalize_tags= function +The =normalize_tags= function is defined as: +#+begin_src sql :exports code :eval never + CREATE OR REPLACE FUNCTION public.normalize_tags(in_tags text[]) + RETURNS text[] + LANGUAGE SQL STRICT IMMUTABLE AS $$ + SELECT ARRAY_AGG(public.normalize_tag(tag)) + FROM UNNEST(in_tags) AS tag; + $$; +#+end_src +* The cause +When testing to see what the criteria SQL would evaluate to, I discovered +something ... interesting. + +#+begin_src sql + SELECT (NOT(public.normalize_tags(ARRAY[]::text[]) @> ARRAY['foo']::text[])) +#+end_src + +#+RESULTS[b0e468c2d8fc47126ee77eb463b2525ff9dca266]: +| ?column? | +|----------| +| | + +That hardly seems right. It's not even returning a boolean. Could it be? + +#+begin_src sql + SELECT (NOT(public.normalize_tags(ARRAY[]::text[]) @> ARRAY['foo']::text[])) IS NULL +#+end_src + +#+RESULTS[c30ad761b00b6d3c038ec008010f17ae5228befd]: +| ?column? | +|----------| +| t | + +Yep. It's returning =NULL=, Tony Hoare's "[[https://www.infoq.com/presentations/Null-References-The-Billion-Dollar-Mistake-Tony-Hoare/][billion-dollar mistake]]". The only +thing different in this implementation is the call to =normalize_tags=, so let's +take a look at that. + +#+begin_src sql + SELECT public.normalize_tags(ARRAY[]::text[]) IS NULL +#+end_src + +#+RESULTS[8a85412be393d1e19d576db8ef321f0ab1380261]: +| ?column? | +|----------| +| t | + +Sure enough, it is returning =NULL= when called with an empty array. That =NULL= then escapes to our array comparison... + +#+begin_src sql + SELECT (NULL @> ARRAY['foo'::text]) IS NULL +#+end_src + +#+RESULTS[80d59a923b98d6ec7adc7af29a53b7557c7c0efc]: +| ?column? | +|----------| +| t | + +... which also returns =NULL=. That then gets passed to =NOT=... + +#+begin_src sql + SELECT (NOT(NULL)) IS NULL +#+end_src + +#+RESULTS[77051c05ab0f6df48e3c13be6ff0651904f8b6da]: +| ?column? | +|----------| +| t | + +... which also returns =NULL=. =NULL= is treated as falsy by [[id:af84ed59-96a4-4f9c-b34c-b79178ad20cb][PostgreSQL]], +and so the search fails to match subscribers without tags. +* The resolution +Using =COALESCE= on the result of =ARRAY_AGG= to ensure we get an empty array +when the result is =NULL=, which lets us avoid all of the above problems caused +by =NULL= escaping into our comparisons. +#+begin_src sql :exports code :eval no-export + CREATE OR REPLACE FUNCTION public.normalize_tags(in_tags text[]) + RETURNS text[] + LANGUAGE SQL STRICT IMMUTABLE AS $$ + SELECT COALESCE(ARRAY_AGG(public.normalize_tag(tag)), ARRAY[]::text[]) + FROM UNNEST(in_tags) AS tag + WHERE public.normalize_tag(tag) <> ''; + $$; +#+end_src + +#+RESULTS[f49761b0fa0e3074cf739102361da7272672f0a1]: +| CREATE FUNCTION | +|-----------------| + +#+begin_src sql + SELECT public.normalize_tags(ARRAY[]::text[]) +#+end_src + +#+RESULTS[a37fd5ae0eaedaf2b33b4886d60d2db0cf632fb5]: +| normalize_tags | +|----------------| +| {} | diff --git a/daily/2022-03-22.org b/daily/2022-03-22.org index 520bc97..2061e3f 100644 --- a/daily/2022-03-22.org +++ b/daily/2022-03-22.org @@ -214,3 +214,130 @@ if the event being compared is a =tag.v1= event. Updated =rulesengine= in https://gitlab.aweber.io/CC/Libraries/rulesengine/-/merge_requests/117. + +** Looking up a campaign's ruleset +Fetch the campaign record using the UUID in the control0-panel campaign URL. +#+begin_src http :pretty :cache yes :exports both + GET http://campaign.service.staging.consul/210b4a4f-ee07-4f1e-98c8-d16541f6e686 +#+end_src + +#+RESULTS[c237f01dc854e750aa1c8f568dbd54f77ab6f56c]: +#+begin_example +{ + "id": "210b4a4f-ee07-4f1e-98c8-d16541f6e686", + "name": "Normal Scott", + "owner": "26b49bc2-207e-4a33-b267-5b9e64f2702e", + "parent": "9f1db623-fbc3-4112-a2f3-ab563e37e131", + "rule_set": "01955ad5-cbca-455c-934f-d69a71a5578f", + "created_at": "2022-03-21T20:17:39.795431+00:00", + "modified_at": "2022-03-24T18:34:37.909620+00:00", + "state_changed_at": "2022-03-22T15:24:45.727430+00:00", + "url": "http://campaign.service.staging.consul/210b4a4f-ee07-4f1e-98c8-d16541f6e686?owner=26b49bc2-207e-4a33-b267-5b9e64f2702e&parent=9f1db623-fbc3-4112-a2f3-ab563e37e131", + "state": "active", + "state_serial": 3, + "is_valid": true, + "is_legacy_followup": false, + "sharing_enabled": false, + "auto_extend_enabled": true, + "extend_needed": false, + "extended_at": null, + "custom_fields": [], + "global_fields": [], + "campaign_type": "autoresponder", + "properties": null +} +#+end_example + +Fetch the rule set using the =rule_set= id returned with the campaign. + +#+begin_src http :pretty :cache yes :exports both + GET https://rule.aweberstage.com/01955ad5-cbca-455c-934f-d69a71a5578f +#+end_src + +#+RESULTS: +#+begin_example +{ + "id": "01955ad5-cbca-455c-934f-d69a71a5578f", + "version": 2, + "owner": "26b49bc2-207e-4a33-b267-5b9e64f2702e", + "parent": "9f1db623-fbc3-4112-a2f3-ab563e37e131", + "state": "active", + "system": false, + "iterator": null, + "events": [ + { + "id": "b3b69bd4-0c7b-4253-ab65-e6fcbb726f07", + "type": "tag.v1", + "title": null, + "filter": { + "type": "all", + "criteria": [ + { + "expect": true, + "kwargs": { + "key": "label", + "values": [ + "normalize test", + "foo" + ] + }, + "function": "rulesengine.filter.event_value_in", + "operator": "==" + }, + { + "expect": true, + "kwargs": { + "list": "", + "labels": [ + "normalize test", + "foo" + ], + "account": "", + "recipient": "" + }, + "function": "ruleset.tag.filter.any_tags_v1", + "operator": "==" + }, + { + "expect": false, + "kwargs": { + "list": "", + "labels": [ + "normalized tag" + ], + "account": "", + "recipient": "" + }, + "function": "ruleset.tag.filter.any_tags_v1", + "operator": "==" + } + ] + }, + "parents": [], + "metadata": "tag.v1", + "recurring": false + } + ], + "actions": [ + { + "id": "396cd5d3-d410-4ae2-a991-b93a0b816600", + "title": null, + "parents": [ + "b3b69bd4-0c7b-4253-ab65-e6fcbb726f07" + ], + "metadata": "send-message", + "recurring": false, + "definition": { + "kwargs": { + "list": "", + "account": "", + "message": "394c27bf-5853-4b45-9ff1-a0637848f4b6", + "meapi_id": "6238dd85f227ef3f2d5ec3a5", + "recipient": "" + }, + "function": "ruleset.email.action.compose_v1" + } + } + ] +} +#+end_example diff --git a/daily/2022-03-29-accounts-with-invalid-tags.png b/daily/2022-03-29-accounts-with-invalid-tags.png new file mode 100644 index 0000000000000000000000000000000000000000..15a824372dbb995d6c0341863571d335e1f65f8a GIT binary patch literal 14637 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 Rlt5+>brsErB}x`={vX(AX4(J% literal 0 HcmV?d00001 diff --git a/daily/2022-03-29-invalid-tag-breakdown.png b/daily/2022-03-29-invalid-tag-breakdown.png new file mode 100644 index 0000000000000000000000000000000000000000..8954966b8c3bba236af8ebab0214a27ae0cd5aee GIT binary patch literal 41936 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 literal 0 HcmV?d00001 diff --git a/daily/2022-03-29-subscribers-with-invalid-tags.png b/daily/2022-03-29-subscribers-with-invalid-tags.png new file mode 100644 index 0000000000000000000000000000000000000000..e2352098a4fb0ef6bbe951b5b53fc0b04518d141 GIT binary patch literal 13927 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 literal 0 HcmV?d00001 diff --git a/daily/2022-03-29.org b/daily/2022-03-29.org index 9317f01..59ceb39 100644 --- a/daily/2022-03-29.org +++ b/daily/2022-03-29.org @@ -28,56 +28,200 @@ rules. WHERE tag != normalize_tag(tag) #+end_src -** Subscribers on active accounts -#+begin_src sql - SELECT COUNT(*) FROM subscribers +** Active accounts +#+name: total-accounts +#+begin_src sql :post humanize-numbers-in-results(results=*this*) + SELECT COUNT(DISTINCT account_id) FROM subscribers #+end_src -#+RESULTS[073c7d5b524a0577c83785ca6051ad010990c18a]: -| count | -|----------| -| 16650026 | +#+RESULTS[5d46a920e8c34c7fd755c2d1fd82ba567f8341d9]: total-accounts +| count | +|---------| +| 103,357 | + +** Subscribers on active accounts +#+name: total-subscribers +#+begin_src sql :post humanize-numbers-in-results(results=*this*) + SELECT COUNT(id) FROM subscribers +#+end_src + +#+RESULTS[17e3b468a66f03b74bdddd77044359dd8e4e92e3]: total-subscribers +| count | +|-------------| +| 259,745,858 | ** Subscribers with invalid tags -#+begin_src sql +#+name: subscribers-with-invalid-tags +#+begin_src sql :post humanize-numbers-in-results(results=*this*) SELECT COUNT(DISTINCT subscriber_id) FROM invalid_tags #+end_src -#+RESULTS[6ff96db184978da7271a89499c58d40cff8daebf]: -| count | -|--------| -| 239291 | +#+RESULTS[b1e6beccd5a3bd4e503473844cb12e6d03d2c21d]: subscribers-with-invalid-tags +| count | +|-----------| +| 1,331,220 | + +#+RESULTS: +#+begin_src emacs-lisp +"259,745,858" +#+end_src + +#+header: :var filename="2022-03-29-subscribers-with-invalid-tags.png" +#+header: :var total=total-subscribers[2,0] +#+header: :var affected=subscribers-with-invalid-tags[2,0] +#+begin_src python :exports results :results file + import matplotlib.pyplot as plt + + plt.style.use("seaborn-pastel") + + total = int(str(total).replace(',', '')) + affected = int(str(affected).replace(',', '')) + + fig1, ax1 = plt.subplots() + ax1.pie( + [affected, total - affected], + explode=[0.5, 0], + labels=[f"Affected", "Unaffected"], + autopct="%1.1f%%", + ) + plt.savefig(filename) + return filename +#+end_src + +#+RESULTS: +[[file:2022-03-29-subscribers-with-invalid-tags.png]] ** Accounts with subscribers with invalid tags -#+begin_src sql +#+name: accounts-with-invalid-tags +#+begin_src sql :post humanize-numbers-in-results(results=*this*) SELECT COUNT(DISTINCT account_id) FROM invalid_tags; #+end_src -#+RESULTS[f45bb88f747f30295132bcd75861b98721cd5341]: +#+RESULTS[0ee163f090d0e32e6a45b5b859948882ffe021d0]: accounts-with-invalid-tags | count | |-------| -| 16 | +| 3,220 | -#+begin_src sql - SELECT DISTINCT account_id FROM invalid_tags +#+header: :var filename="2022-03-29-accounts-with-invalid-tags.png" +#+header: :var total=total-accounts[2,0] +#+header: :var affected=accounts-with-invalid-tags[2,0] +#+begin_src python :exports results :results file + import matplotlib.pyplot as plt + + plt.style.use("seaborn-pastel") + + total = int(str(total).replace(',', '')) + affected = int(str(affected).replace(',', '')) + + fig1, ax1 = plt.subplots() + ax1.pie( + [affected, total - affected], + explode=[0.5, 0], + labels=[f"Affected", "Unaffected"], + autopct="%1.1f%%", + ) + plt.savefig(filename) + return filename #+end_src -#+RESULTS[ff2ba7ea0c8dc285f2be2a20afb0d0c786f4dac1]: -| account_id | -|------------| -| 1833 | -| 211344 | -| 13492 | -| 212837 | -| 216738 | -| 213819 | -| 16479 | -| 215217 | -| 104120 | -| 215067 | -| 213122 | -| 14656 | -| 111262 | -| 214928 | -| 44749 | -| 91 | +#+RESULTS: +[[file:2022-03-29-accounts-with-invalid-tags.png]] + +** Normalized tag breakdown +#+name: tag-breakdown +#+begin_src sql :post humanize-numbers-in-results(results=*this*) + SELECT 'Non-printable characters' AS "Rule" + , COUNT(DISTINCT account_id) AS "Accounts" + , COUNT(subscriber_id) AS "Subscribers" + FROM invalid_tags + WHERE tag ~ '[^[:print:]]' + UNION SELECT 'Commas' AS "Rule" + , COUNT(DISTINCT account_id) AS "Accounts" + , COUNT(subscriber_id) AS "Subscribers" + FROM invalid_tags + WHERE tag ~ ',' + UNION SELECT 'ASCII quotation marks' AS "Rule" + , COUNT(DISTINCT account_id) AS "Accounts" + , COUNT(subscriber_id) AS "Subscribers" + FROM invalid_tags + WHERE tag ~ '[''""]' + UNION SELECT 'Unicode quotation marks' AS "Rule" + , COUNT(DISTINCT account_id) AS "Accounts" + , COUNT(subscriber_id) AS "Subscribers" + FROM invalid_tags + WHERE tag ~ '[‘’“”]' + UNION SELECT 'Leading or trailing whitespace' AS "Rule" + , COUNT(DISTINCT account_id) AS "Accounts" + , COUNT(subscriber_id) AS "Subscribers" + FROM invalid_tags + WHERE TRIM(tag) != tag + UNION SELECT 'Repeated whitespace' AS "Rule" + , COUNT(DISTINCT account_id) AS "Accounts" + , COUNT(subscriber_id) AS "Subscribers" + FROM invalid_tags + WHERE TRIM(tag) ~ '[:space:]{2,}' + UNION SELECT 'Upper-case characters' AS "Rule" + , COUNT(DISTINCT account_id) AS "Accounts" + , COUNT(subscriber_id) AS "Subscribers" + FROM invalid_tags + WHERE LOWER(tag) != tag +#+end_src + +#+RESULTS[853c04719cf6fd9c329359c1b72e8198393322b9]: tag-breakdown +| Rule | Accounts | Subscribers | +|--------------------------------+----------+-------------| +| Leading or trailing whitespace | 119 | 66,788 | +| Repeated whitespace | 2,404 | 1,234,651 | +| Unicode quotation marks | 126 | 21,343 | +| Commas | 378 | 54,567 | +| ASCII quotation marks | 2,507 | 1,544,607 | +| Upper-case characters | 0 | 0 | +| Non-printable characters | 58 | 1,749 | + +#+header: :var filename="2022-03-29-invalid-tag-breakdown.png" +#+header: :var breakdown=tag-breakdown +#+begin_src python :exports results :results file + import matplotlib.pyplot as plt + + plt.style.use("seaborn-pastel") + + accounts = sorted( + [(int(str(row[1]).replace(",", "")), row[0]) for row in breakdown], + reverse=True, + ) + account_total = sum(a[0] for a in accounts) + subscribers = sorted( + [(int(str(row[2]).replace(",", "")), row[0]) for row in breakdown], + reverse=True, + ) + subscriber_total = sum(s[0] for s in subscribers) + + fig1, axs = plt.subplots(2, 2) + axs[0, 0].set_title("Accounts") + wedges1, _ = axs[0, 0].pie( + [a[0] for a in accounts], + explode=[0.1 for _ in accounts], + ) + axs[1, 0].axis("off") + axs[1, 0].legend( + wedges1, + ["{:.1f}% {}".format(a[0] * 100.0 / account_total, a[1]) for a in accounts], + fontsize=8, + ) + axs[0, 1].set_title("Subscribers") + wedges2, _ = axs[0, 1].pie( + [s[0] for s in subscribers], + explode=[0.1 for _ in subscribers], + ) + axs[1, 1].axis("off") + axs[1, 1].legend( + wedges2, + ["{:.1f}% {}".format(s[0] * 100.0 / subscriber_total, s[1]) for s in subscribers], + fontsize=8, + ) + plt.savefig(filename) + return filename +#+end_src + +#+RESULTS: +[[file:2022-03-29-invalid-tag-breakdown.png]] diff --git a/daily/2022-04-06.org b/daily/2022-04-06.org new file mode 100644 index 0000000..ef116cc --- /dev/null +++ b/daily/2022-04-06.org @@ -0,0 +1,27 @@ +:PROPERTIES: +:ID: 091bce6d-e15b-434f-a7be-bc6627a71925 +:END: +#+title: 2022-04-06 +* Fixing normalized tag search +https://jira.aweber.io/browse/ASE-8617 + +- *What was broken?* :: Searches and segments with a "tag is not" constraint + failed to match subscribers with no tags. +- *When was it broken?* :: April 5th at 16:00, following the release of + CCPANEL-12034. +- *What did you do to fix the problem?* :: The change was rolled back by + updating search terms in the analytics search database to their previous + values at 19:12 on April 5th. +- *How many customers did it likely impact?* :: Likely all customers using the + "tag not in" filter in their searches and segments. +- *Is the issue automatically fixed for all customers now?* :: Yes. +- *Does the customer or CS need to manually do something to fix their account?* :: No. +- *Should a new monitoring check, metric, or test be created to prevent this from happening again?* :: Additional + tests will be added to ensure future releases of this feature do not break + search and segment behavior. +** What happened? +=ARRAY_AGG= returns =NULL= when given an empty set. This breaks the tag +comparison, as =NOT(NULL @> ARRAY['tag'])= is equal to =NULL=, not =TRUE=. +Updating the logic to =COALESCE= null values with an empty array allows the +comparison to function as intended. =normalize_tags= must also omit invalid tags +(tags that normalize to the empty string) from its results. diff --git a/daily/2022-04-07.org b/daily/2022-04-07.org new file mode 100644 index 0000000..f8aaf26 --- /dev/null +++ b/daily/2022-04-07.org @@ -0,0 +1,92 @@ +:PROPERTIES: +:ID: 5762836c-ef1f-43f5-9562-3bc38ae411ed +:END: +#+title: 2022-04-07 +* Verifying search tag normalization changes +:PROPERTIES: +:header-args:sql: :engine postgresql :cmdline "-U postgres postgres" :dir /docker:postgres: :exports both :cache yes +:END: +- https://jira.aweber.io/browse/ASE-8617 +- https://admin.aweber.io/account/index/1018872 +- List 5830776 + +#+caption: Segment definition: "no tags subscribers" + | Tag | is not | wr | + | Tag | is not | cb | + | Tag | is not | cb2 | + | Tag | is not | fsc | + | Tag | is not | flp | + | Tag | is not | lsa | +** Using the old =normalize_tags= implementation +#+begin_src sql :eval never + CREATE OR REPLACE FUNCTION public.normalize_tags(in_tags text[]) + RETURNS text[] + LANGUAGE SQL STRICT IMMUTABLE AS $$ + SELECT ARRAY_AGG(public.normalize_tag(tag)) + FROM UNNEST(in_tags) AS tag; + $$; + + SELECT COUNT(t.subscriber_id) + FROM subscriber_tags AS t + JOIN subscribers AS s ON (s.id = t.subscriber_id) + WHERE s.account_id = 1018872 AND s.list_id = 5830776 + AND NOT(public.normalize_tags(t.tags) @> public.normalize_tags(ARRAY['wr'::text])) + AND NOT(public.normalize_tags(t.tags) @> public.normalize_tags(ARRAY['cb'::text])) + AND NOT(public.normalize_tags(t.tags) @> public.normalize_tags(ARRAY['cb2'::text])) + AND NOT(public.normalize_tags(t.tags) @> public.normalize_tags(ARRAY['fsc'::text])) + AND NOT(public.normalize_tags(t.tags) @> public.normalize_tags(ARRAY['flp'::text])) + AND NOT(public.normalize_tags(t.tags) @> public.normalize_tags(ARRAY['lsa'::text])); +#+end_src + +#+RESULTS[d56d997121fe4f3ff98458e18fba912650d44796]: +| CREATE FUNCTION | +|-----------------| +| count | +| 0 | + +** Using the old comparisons +#+begin_src sql :eval never + SELECT COUNT(t.subscriber_id) + FROM subscriber_tags AS t + JOIN subscribers AS s ON (s.id = t.subscriber_id) + WHERE s.account_id = 1018872 AND s.list_id = 5830776 + AND NOT(t.tags @> ARRAY['wr'::text]) + AND NOT(t.tags @> ARRAY['cb'::text]) + AND NOT(t.tags @> ARRAY['cb2'::text]) + AND NOT(t.tags @> ARRAY['fsc'::text]) + AND NOT(t.tags @> ARRAY['flp'::text]) + AND NOT(t.tags @> ARRAY['lsa'::text]); +#+end_src + +#+RESULTS[792264b3be7d158bb6bda1124a4e23f4a19ada06]: +| count | +|-------| +| 1016 | + +** Using the new =normalize_tags= implementation +#+begin_src sql :eval never + CREATE OR REPLACE FUNCTION public.normalize_tags(in_tags text[]) + RETURNS text[] + LANGUAGE SQL STRICT IMMUTABLE AS $$ + SELECT COALESCE(ARRAY_AGG(public.normalize_tag(tag)), ARRAY[]::text[]) + FROM UNNEST(in_tags) AS tag + WHERE public.normalize_tag(tag) <> ''; + $$; + + SELECT COUNT(t.subscriber_id) + FROM subscriber_tags AS t + JOIN subscribers AS s ON (s.id = t.subscriber_id) + WHERE s.account_id = 1018872 AND s.list_id = 5830776 + AND NOT(public.normalize_tags(t.tags) @> public.normalize_tags(ARRAY['wr'::text])) + AND NOT(public.normalize_tags(t.tags) @> public.normalize_tags(ARRAY['cb'::text])) + AND NOT(public.normalize_tags(t.tags) @> public.normalize_tags(ARRAY['cb2'::text])) + AND NOT(public.normalize_tags(t.tags) @> public.normalize_tags(ARRAY['fsc'::text])) + AND NOT(public.normalize_tags(t.tags) @> public.normalize_tags(ARRAY['flp'::text])) + AND NOT(public.normalize_tags(t.tags) @> public.normalize_tags(ARRAY['lsa'::text])); +#+end_src + +#+RESULTS[ae72571ff73254fc70555db4517f759ddfdfcc8c]: +| CREATE FUNCTION | +|-----------------| +| count | +| 1016 | diff --git a/daily/2022-04-12.org b/daily/2022-04-12.org new file mode 100644 index 0000000..1f49ca1 --- /dev/null +++ b/daily/2022-04-12.org @@ -0,0 +1,144 @@ +:PROPERTIES: +:ID: b1d8fa03-4bd6-4bae-a642-23ae77769c41 +:END: +#+title: 2022-04-12 +* Normalizing tags in rule sets +References for applying [[id:d06d3ab4-c2d0-47c3-aae1-4395567fc3d2][Tag Normalization]] to campaign rule sets. + +Campaign proxy iterates through this data, could be useful as an example. +** References for navigating rule set data structures +- Ruleset structure :: https://confluence.aweber.io/display/AR/Ruleset+v2+Structure#Rulesetv2Structure-event +- Ruleset json schemas :: https://gitlab.aweber.io/CC/Libraries/ruleset-json-schema/-/tree/master +- Campaigns iterating through events :: https://gitlab.aweber.io/CC/Applications/campaign-proxy/-/blob/4eafb44c557aff34a0c9b519ff99d6c81eb9b0d8/campaignproxy/ruleset_validation_handlers.py#L442-447 +- Campaigns iterating through actions :: https://gitlab.aweber.io/CC/Applications/campaign-proxy/-/blob/4eafb44c557aff34a0c9b519ff99d6c81eb9b0d8/campaignproxy/ruleset_validation_handlers.py#L402-403 + +#+begin_notes +The rule service also stores data for searches in redis, be sure to alter the +data before any storage occurs. +#+end_notes +** Looking up a campaign's ruleset +Fetch the campaign record using the UUID in the control0-panel campaign URL. +#+begin_src http :pretty :cache yes :exports both + GET http://campaign.service.staging.consul/210b4a4f-ee07-4f1e-98c8-d16541f6e686 +#+end_src + +#+RESULTS[c237f01dc854e750aa1c8f568dbd54f77ab6f56c]: +#+begin_example +{ + "id": "210b4a4f-ee07-4f1e-98c8-d16541f6e686", + "name": "Normal Scott", + "owner": "26b49bc2-207e-4a33-b267-5b9e64f2702e", + "parent": "9f1db623-fbc3-4112-a2f3-ab563e37e131", + "rule_set": "01955ad5-cbca-455c-934f-d69a71a5578f", + "created_at": "2022-03-21T20:17:39.795431+00:00", + "modified_at": "2022-03-24T18:34:37.909620+00:00", + "state_changed_at": "2022-03-22T15:24:45.727430+00:00", + "url": "http://campaign.service.staging.consul/210b4a4f-ee07-4f1e-98c8-d16541f6e686?owner=26b49bc2-207e-4a33-b267-5b9e64f2702e&parent=9f1db623-fbc3-4112-a2f3-ab563e37e131", + "state": "active", + "state_serial": 3, + "is_valid": true, + "is_legacy_followup": false, + "sharing_enabled": false, + "auto_extend_enabled": true, + "extend_needed": false, + "extended_at": null, + "custom_fields": [], + "global_fields": [], + "campaign_type": "autoresponder", + "properties": null +} +#+end_example + +Fetch the rule set using the =rule_set= id returned with the campaign. + +#+begin_src http :pretty :cache yes :exports both + GET https://rule.aweberstage.com/01955ad5-cbca-455c-934f-d69a71a5578f +#+end_src + +#+RESULTS[685774a46bbaf38b945afcc0952a390d1bc53ed3]: +#+begin_example +{ + "id": "01955ad5-cbca-455c-934f-d69a71a5578f", + "version": 2, + "owner": "26b49bc2-207e-4a33-b267-5b9e64f2702e", + "parent": "9f1db623-fbc3-4112-a2f3-ab563e37e131", + "state": "active", + "system": false, + "iterator": null, + "events": [ + { + "id": "b3b69bd4-0c7b-4253-ab65-e6fcbb726f07", + "type": "tag.v1", + "title": null, + "filter": { + "type": "all", + "criteria": [ + { + "expect": true, + "kwargs": { + "key": "label", + "values": [ + "normalize test", + "foo" + ] + }, + "function": "rulesengine.filter.event_value_in", + "operator": "==" + }, + { + "expect": true, + "kwargs": { + "list": "", + "labels": [ + "normalize test", + "foo" + ], + "account": "", + "recipient": "" + }, + "function": "ruleset.tag.filter.any_tags_v1", + "operator": "==" + }, + { + "expect": false, + "kwargs": { + "list": "", + "labels": [ + "normalized tag" + ], + "account": "", + "recipient": "" + }, + "function": "ruleset.tag.filter.any_tags_v1", + "operator": "==" + } + ] + }, + "parents": [], + "metadata": "tag.v1", + "recurring": false + } + ], + "actions": [ + { + "id": "396cd5d3-d410-4ae2-a991-b93a0b816600", + "title": null, + "parents": [ + "b3b69bd4-0c7b-4253-ab65-e6fcbb726f07" + ], + "metadata": "send-message", + "recurring": false, + "definition": { + "kwargs": { + "list": "", + "account": "", + "message": "394c27bf-5853-4b45-9ff1-a0637848f4b6", + "meapi_id": "6238dd85f227ef3f2d5ec3a5", + "recipient": "" + }, + "function": "ruleset.email.action.compose_v1" + } + } + ] +} +#+end_example