Re: [PATCH] Support for MO direction 'group = smsbox-route' reloading (aka graceful restart)

[email protected] Mon, 15 Oct 2018 17:33:23 +0200
Newsgroups gmane.comp.mobile.kannel.devel
Message-ID <[email protected]>
--Apple-Mail=_16D4F14A-E7CF-45A5-A302-1AE1FB237AFF
Content-Transfer-Encoding: quoted-printable
Content-Type: text/plain;
	charset=utf-8

Hi Stipe,

sorry I was not available earlier=E2=80=A6

just checked your patch and see man many issues=E2=80=A6

1.=20

+static void init_smsbox_routes(Cfg *cfg, int reload)

you use continue if config is wrong

but you already destroyed previous configuration

-    /* send new config to clients */
+    gw_rwlock_wrlock(smsbox_list_rwlock);
+    dict_destroy(smsbox_by_smsc);
+    dict_destroy(smsbox_by_receiver);
+    dict_destroy(smsbox_by_smsc_receiver);
+    smsbox_by_smsc =3D dict_create(30, (void(*)(void *)) =
octstr_destroy);
+    smsbox_by_receiver =3D dict_create(50, (void(*)(void *)) =
octstr_destroy);
+    smsbox_by_smsc_receiver =3D dict_create(50, (void(*)(void *)) =
octstr_destroy);
+    init_smsbox_routes(cfg, 1);
+    gw_rwlock_unlock(smsbox_list_rwlock);

That means, you have inconsistency


2. if I see reload configs without a lock=E2=80=A6 Uhh I can construct =
soo many cases, e.g. smsc is renamed in new config but still used in the =
old smsbox group, etc. etc.

 int bb_graceful_restart(void)
 {
-    return smsc2_graceful_restart();
+    Cfg *cfg;
+
+    info(0, "Reloading configuration resource `%s'.", =
octstr_get_cstr(cfg_filename));
+    cfg =3D cfg_create(cfg_filename);
+    if (cfg_read(cfg) =3D=3D -1) {
+        error(0, "Error processing configuration resource `%s'. =
Continue with existing configuration.",
+              octstr_get_cstr(cfg_filename));
+        return -1;
+    }
+
+    smsc2_graceful_restart(cfg);
+    smsbox_restart(cfg);
+    return 0;
 }


Reload has to be atomic operation otherwise you will have some time =
inconsistent state.

Thanks,
Alex




> Am 15.10.2018 um 15:10 schrieb Stipe Tolj <[email protected]>:
>=20
> Am 01.10.2018 14:56, schrieb Stipe Tolj:
>> Hi all,
>>=20
>> the reloading of the config (aka graceful restart) supports the
>> on-th-fly manipulation of the upstream SMSC groups and the =
corresponding
>> routing constraints for them.
>>=20
>> What is doesn't support is the on-the-fly changing of the 'group =3D
>> smsbox-route' MO direction routing.
>>=20
>> The attached patch adds this capability.
>>=20
>> Please review. If no objections arise I will commit this within the =
next
>> days.
>=20
> committed to svn trunk, r5269.
>=20
> --=20
> Best Regards,
> Stipe Tolj
>=20
> -------------------------------------------------------------------
> D=C3=BCsseldorf, NRW, Germany
>=20
> Kannel Foundation                 tolj.org <http://tolj.org/> system =
architecture
> http://www.kannel.org/ <http://www.kannel.org/>            =
http://www.tolj.org/ <http://www.tolj.org/>
>=20
> stolj at kannel.org <http://kannel.org/>               st at tolj.org =
<http://tolj.org/>
> -------------------------------------------------------------------
>=20


--Apple-Mail=_16D4F14A-E7CF-45A5-A302-1AE1FB237AFF
Content-Transfer-Encoding: quoted-printable
Content-Type: text/html;
	charset=utf-8

<html><head><meta http-equiv=3D"Content-Type" content=3D"text/html; =
charset=3Dutf-8"></head><body style=3D"word-wrap: break-word; =
-webkit-nbsp-mode: space; line-break: after-white-space;" class=3D"">Hi =
Stipe,<div class=3D""><br class=3D""></div><div class=3D"">sorry I was =
not available earlier=E2=80=A6</div><div class=3D""><br =
class=3D""></div><div class=3D"">just checked your patch and see man =
many issues=E2=80=A6</div><div class=3D""><br class=3D""></div><div =
class=3D"">1.&nbsp;</div><div class=3D""><br class=3D""></div><div =
class=3D""><div class=3D"">+static void init_smsbox_routes(Cfg *cfg, int =
reload)</div><div class=3D""><br class=3D""></div><div class=3D"">you =
use continue if config is wrong</div><div class=3D""><br =
class=3D""></div><div class=3D"">but you already destroyed previous =
configuration</div><div class=3D""><br class=3D""></div><div =
class=3D""><div class=3D"">- &nbsp; &nbsp;/* send new config to clients =
*/</div><div class=3D"">+ &nbsp; =
&nbsp;gw_rwlock_wrlock(smsbox_list_rwlock);</div><div class=3D"">+ =
&nbsp; &nbsp;dict_destroy(smsbox_by_smsc);</div><div class=3D"">+ &nbsp; =
&nbsp;dict_destroy(smsbox_by_receiver);</div><div class=3D"">+ &nbsp; =
&nbsp;dict_destroy(smsbox_by_smsc_receiver);</div><div class=3D"">+ =
&nbsp; &nbsp;smsbox_by_smsc =3D dict_create(30, (void(*)(void *)) =
octstr_destroy);</div><div class=3D"">+ &nbsp; &nbsp;smsbox_by_receiver =
=3D dict_create(50, (void(*)(void *)) octstr_destroy);</div><div =
class=3D"">+ &nbsp; &nbsp;smsbox_by_smsc_receiver =3D dict_create(50, =
(void(*)(void *)) octstr_destroy);</div><div class=3D"">+ &nbsp; =
&nbsp;init_smsbox_routes(cfg, 1);</div><div class=3D"">+ &nbsp; =
&nbsp;gw_rwlock_unlock(smsbox_list_rwlock);</div></div><div class=3D""><br=
 class=3D""></div><div class=3D"">That means, you have =
inconsistency</div><div class=3D""><br class=3D""></div><div =
class=3D""><br class=3D""></div><div class=3D"">2. if I see reload =
configs without a lock=E2=80=A6 Uhh I can construct soo many cases, e.g. =
smsc is renamed in new config but still used in the old smsbox group, =
etc. etc.</div><div class=3D""><br class=3D""></div><div class=3D""><div =
class=3D"">&nbsp;int bb_graceful_restart(void)</div><div =
class=3D"">&nbsp;{</div><div class=3D"">- &nbsp; &nbsp;return =
smsc2_graceful_restart();</div><div class=3D"">+ &nbsp; &nbsp;Cfg =
*cfg;</div><div class=3D"">+</div><div class=3D"">+ &nbsp; &nbsp;info(0, =
"Reloading configuration resource `%s'.", =
octstr_get_cstr(cfg_filename));</div><div class=3D"">+ &nbsp; &nbsp;cfg =
=3D cfg_create(cfg_filename);</div><div class=3D"">+ &nbsp; &nbsp;if =
(cfg_read(cfg) =3D=3D -1) {</div><div class=3D"">+ &nbsp; &nbsp; &nbsp; =
&nbsp;error(0, "Error processing configuration resource `%s'. Continue =
with existing configuration.",</div><div class=3D"">+ &nbsp; &nbsp; =
&nbsp; &nbsp; &nbsp; &nbsp; =
&nbsp;octstr_get_cstr(cfg_filename));</div><div class=3D"">+ &nbsp; =
&nbsp; &nbsp; &nbsp;return -1;</div><div class=3D"">+ &nbsp; =
&nbsp;}</div><div class=3D"">+</div><div class=3D"">+ &nbsp; =
&nbsp;smsc2_graceful_restart(cfg);</div><div class=3D"">+ &nbsp; =
&nbsp;smsbox_restart(cfg);</div><div class=3D"">+ &nbsp; &nbsp;return =
0;</div><div class=3D"">&nbsp;}</div></div><div class=3D""><br =
class=3D""></div><div class=3D""><br class=3D""></div><div =
class=3D"">Reload has to be atomic operation otherwise you will have =
some time inconsistent state.</div><div class=3D""><br =
class=3D""></div><div class=3D"">Thanks,</div><div =
class=3D"">Alex</div><div class=3D""><br class=3D""></div><div =
class=3D""><br class=3D""></div><div class=3D""><br =
class=3D""></div><div><br class=3D""><blockquote type=3D"cite" =
class=3D""><div class=3D"">Am 15.10.2018 um 15:10 schrieb Stipe Tolj =
&lt;<a href=3D"mailto:[email protected]" =
class=3D"">[email protected]</a>&gt;:</div><br =
class=3D"Apple-interchange-newline"><div class=3D""><span =
style=3D"caret-color: rgb(0, 0, 0); font-family: Helvetica; font-size: =
12px; font-style: normal; font-variant-caps: normal; font-weight: =
normal; letter-spacing: normal; text-align: start; text-indent: 0px; =
text-transform: none; white-space: normal; word-spacing: 0px; =
-webkit-text-stroke-width: 0px; text-decoration: none; float: none; =
display: inline !important;" class=3D"">Am 01.10.2018 14:56, schrieb =
Stipe Tolj:</span><br style=3D"caret-color: rgb(0, 0, 0); font-family: =
Helvetica; font-size: 12px; font-style: normal; font-variant-caps: =
normal; font-weight: normal; letter-spacing: normal; text-align: start; =
text-indent: 0px; text-transform: none; white-space: normal; =
word-spacing: 0px; -webkit-text-stroke-width: 0px; text-decoration: =
none;" class=3D""><blockquote type=3D"cite" style=3D"font-family: =
Helvetica; font-size: 12px; font-style: normal; font-variant-caps: =
normal; font-weight: normal; letter-spacing: normal; orphans: auto; =
text-align: start; text-indent: 0px; text-transform: none; white-space: =
normal; widows: auto; word-spacing: 0px; -webkit-text-size-adjust: auto; =
-webkit-text-stroke-width: 0px; text-decoration: none;" class=3D"">Hi =
all,<br class=3D""><br class=3D"">the reloading of the config (aka =
graceful restart) supports the<br class=3D"">on-th-fly manipulation of =
the upstream SMSC groups and the corresponding<br class=3D"">routing =
constraints for them.<br class=3D""><br class=3D"">What is doesn't =
support is the on-the-fly changing of the 'group =3D<br =
class=3D"">smsbox-route' MO direction routing.<br class=3D""><br =
class=3D"">The attached patch adds this capability.<br class=3D""><br =
class=3D"">Please review. If no objections arise I will commit this =
within the next<br class=3D"">days.<br class=3D""></blockquote><br =
style=3D"caret-color: rgb(0, 0, 0); font-family: Helvetica; font-size: =
12px; font-style: normal; font-variant-caps: normal; font-weight: =
normal; letter-spacing: normal; text-align: start; text-indent: 0px; =
text-transform: none; white-space: normal; word-spacing: 0px; =
-webkit-text-stroke-width: 0px; text-decoration: none;" class=3D""><span =
style=3D"caret-color: rgb(0, 0, 0); font-family: Helvetica; font-size: =
12px; font-style: normal; font-variant-caps: normal; font-weight: =
normal; letter-spacing: normal; text-align: start; text-indent: 0px; =
text-transform: none; white-space: normal; word-spacing: 0px; =
-webkit-text-stroke-width: 0px; text-decoration: none; float: none; =
display: inline !important;" class=3D"">committed to svn trunk, =
r5269.</span><br style=3D"caret-color: rgb(0, 0, 0); font-family: =
Helvetica; font-size: 12px; font-style: normal; font-variant-caps: =
normal; font-weight: normal; letter-spacing: normal; text-align: start; =
text-indent: 0px; text-transform: none; white-space: normal; =
word-spacing: 0px; -webkit-text-stroke-width: 0px; text-decoration: =
none;" class=3D""><br style=3D"caret-color: rgb(0, 0, 0); font-family: =
Helvetica; font-size: 12px; font-style: normal; font-variant-caps: =
normal; font-weight: normal; letter-spacing: normal; text-align: start; =
text-indent: 0px; text-transform: none; white-space: normal; =
word-spacing: 0px; -webkit-text-stroke-width: 0px; text-decoration: =
none;" class=3D""><span style=3D"caret-color: rgb(0, 0, 0); font-family: =
Helvetica; font-size: 12px; font-style: normal; font-variant-caps: =
normal; font-weight: normal; letter-spacing: normal; text-align: start; =
text-indent: 0px; text-transform: none; white-space: normal; =
word-spacing: 0px; -webkit-text-stroke-width: 0px; text-decoration: =
none; float: none; display: inline !important;" class=3D"">--<span =
class=3D"Apple-converted-space">&nbsp;</span></span><br =
style=3D"caret-color: rgb(0, 0, 0); font-family: Helvetica; font-size: =
12px; font-style: normal; font-variant-caps: normal; font-weight: =
normal; letter-spacing: normal; text-align: start; text-indent: 0px; =
text-transform: none; white-space: normal; word-spacing: 0px; =
-webkit-text-stroke-width: 0px; text-decoration: none;" class=3D""><span =
style=3D"caret-color: rgb(0, 0, 0); font-family: Helvetica; font-size: =
12px; font-style: normal; font-variant-caps: normal; font-weight: =
normal; letter-spacing: normal; text-align: start; text-indent: 0px; =
text-transform: none; white-space: normal; word-spacing: 0px; =
-webkit-text-stroke-width: 0px; text-decoration: none; float: none; =
display: inline !important;" class=3D"">Best Regards,</span><br =
style=3D"caret-color: rgb(0, 0, 0); font-family: Helvetica; font-size: =
12px; font-style: normal; font-variant-caps: normal; font-weight: =
normal; letter-spacing: normal; text-align: start; text-indent: 0px; =
text-transform: none; white-space: normal; word-spacing: 0px; =
-webkit-text-stroke-width: 0px; text-decoration: none;" class=3D""><span =
style=3D"caret-color: rgb(0, 0, 0); font-family: Helvetica; font-size: =
12px; font-style: normal; font-variant-caps: normal; font-weight: =
normal; letter-spacing: normal; text-align: start; text-indent: 0px; =
text-transform: none; white-space: normal; word-spacing: 0px; =
-webkit-text-stroke-width: 0px; text-decoration: none; float: none; =
display: inline !important;" class=3D"">Stipe Tolj</span><br =
style=3D"caret-color: rgb(0, 0, 0); font-family: Helvetica; font-size: =
12px; font-style: normal; font-variant-caps: normal; font-weight: =
normal; letter-spacing: normal; text-align: start; text-indent: 0px; =
text-transform: none; white-space: normal; word-spacing: 0px; =
-webkit-text-stroke-width: 0px; text-decoration: none;" class=3D""><br =
style=3D"caret-color: rgb(0, 0, 0); font-family: Helvetica; font-size: =
12px; font-style: normal; font-variant-caps: normal; font-weight: =
normal; letter-spacing: normal; text-align: start; text-indent: 0px; =
text-transform: none; white-space: normal; word-spacing: 0px; =
-webkit-text-stroke-width: 0px; text-decoration: none;" class=3D""><span =
style=3D"caret-color: rgb(0, 0, 0); font-family: Helvetica; font-size: =
12px; font-style: normal; font-variant-caps: normal; font-weight: =
normal; letter-spacing: normal; text-align: start; text-indent: 0px; =
text-transform: none; white-space: normal; word-spacing: 0px; =
-webkit-text-stroke-width: 0px; text-decoration: none; float: none; =
display: inline !important;" =
class=3D"">---------------------------------------------------------------=
----</span><br style=3D"caret-color: rgb(0, 0, 0); font-family: =
Helvetica; font-size: 12px; font-style: normal; font-variant-caps: =
normal; font-weight: normal; letter-spacing: normal; text-align: start; =
text-indent: 0px; text-transform: none; white-space: normal; =
word-spacing: 0px; -webkit-text-stroke-width: 0px; text-decoration: =
none;" class=3D""><span style=3D"caret-color: rgb(0, 0, 0); font-family: =
Helvetica; font-size: 12px; font-style: normal; font-variant-caps: =
normal; font-weight: normal; letter-spacing: normal; text-align: start; =
text-indent: 0px; text-transform: none; white-space: normal; =
word-spacing: 0px; -webkit-text-stroke-width: 0px; text-decoration: =
none; float: none; display: inline !important;" class=3D"">D=C3=BCsseldorf=
, NRW, Germany</span><br style=3D"caret-color: rgb(0, 0, 0); =
font-family: Helvetica; font-size: 12px; font-style: normal; =
font-variant-caps: normal; font-weight: normal; letter-spacing: normal; =
text-align: start; text-indent: 0px; text-transform: none; white-space: =
normal; word-spacing: 0px; -webkit-text-stroke-width: 0px; =
text-decoration: none;" class=3D""><br style=3D"caret-color: rgb(0, 0, =
0); font-family: Helvetica; font-size: 12px; font-style: normal; =
font-variant-caps: normal; font-weight: normal; letter-spacing: normal; =
text-align: start; text-indent: 0px; text-transform: none; white-space: =
normal; word-spacing: 0px; -webkit-text-stroke-width: 0px; =
text-decoration: none;" class=3D""><span style=3D"caret-color: rgb(0, 0, =
0); font-family: Helvetica; font-size: 12px; font-style: normal; =
font-variant-caps: normal; font-weight: normal; letter-spacing: normal; =
text-align: start; text-indent: 0px; text-transform: none; white-space: =
normal; word-spacing: 0px; -webkit-text-stroke-width: 0px; =
text-decoration: none; float: none; display: inline !important;" =
class=3D"">Kannel Foundation =
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&n=
bsp;&nbsp;&nbsp;&nbsp;</span><a href=3D"http://tolj.org/" =
style=3D"font-family: Helvetica; font-size: 12px; font-style: normal; =
font-variant-caps: normal; font-weight: normal; letter-spacing: normal; =
orphans: auto; text-align: start; text-indent: 0px; text-transform: =
none; white-space: normal; widows: auto; word-spacing: 0px; =
-webkit-text-size-adjust: auto; -webkit-text-stroke-width: 0px;" =
class=3D"">tolj.org</a><span style=3D"caret-color: rgb(0, 0, 0); =
font-family: Helvetica; font-size: 12px; font-style: normal; =
font-variant-caps: normal; font-weight: normal; letter-spacing: normal; =
text-align: start; text-indent: 0px; text-transform: none; white-space: =
normal; word-spacing: 0px; -webkit-text-stroke-width: 0px; =
text-decoration: none; float: none; display: inline !important;" =
class=3D""><span class=3D"Apple-converted-space">&nbsp;</span>system =
architecture</span><br style=3D"caret-color: rgb(0, 0, 0); font-family: =
Helvetica; font-size: 12px; font-style: normal; font-variant-caps: =
normal; font-weight: normal; letter-spacing: normal; text-align: start; =
text-indent: 0px; text-transform: none; white-space: normal; =
word-spacing: 0px; -webkit-text-stroke-width: 0px; text-decoration: =
none;" class=3D""><a href=3D"http://www.kannel.org/" style=3D"font-family:=
 Helvetica; font-size: 12px; font-style: normal; font-variant-caps: =
normal; font-weight: normal; letter-spacing: normal; orphans: auto; =
text-align: start; text-indent: 0px; text-transform: none; white-space: =
normal; widows: auto; word-spacing: 0px; -webkit-text-size-adjust: auto; =
-webkit-text-stroke-width: 0px;" =
class=3D"">http://www.kannel.org/</a><span style=3D"caret-color: rgb(0, =
0, 0); font-family: Helvetica; font-size: 12px; font-style: normal; =
font-variant-caps: normal; font-weight: normal; letter-spacing: normal; =
text-align: start; text-indent: 0px; text-transform: none; white-space: =
normal; word-spacing: 0px; -webkit-text-stroke-width: 0px; =
text-decoration: none; float: none; display: inline !important;" =
class=3D""><span =
class=3D"Apple-converted-space">&nbsp;</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp=
;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><a =
href=3D"http://www.tolj.org/" style=3D"font-family: Helvetica; =
font-size: 12px; font-style: normal; font-variant-caps: normal; =
font-weight: normal; letter-spacing: normal; orphans: auto; text-align: =
start; text-indent: 0px; text-transform: none; white-space: normal; =
widows: auto; word-spacing: 0px; -webkit-text-size-adjust: auto; =
-webkit-text-stroke-width: 0px;" class=3D"">http://www.tolj.org/</a><br =
style=3D"caret-color: rgb(0, 0, 0); font-family: Helvetica; font-size: =
12px; font-style: normal; font-variant-caps: normal; font-weight: =
normal; letter-spacing: normal; text-align: start; text-indent: 0px; =
text-transform: none; white-space: normal; word-spacing: 0px; =
-webkit-text-stroke-width: 0px; text-decoration: none;" class=3D""><br =
style=3D"caret-color: rgb(0, 0, 0); font-family: Helvetica; font-size: =
12px; font-style: normal; font-variant-caps: normal; font-weight: =
normal; letter-spacing: normal; text-align: start; text-indent: 0px; =
text-transform: none; white-space: normal; word-spacing: 0px; =
-webkit-text-stroke-width: 0px; text-decoration: none;" class=3D""><span =
style=3D"caret-color: rgb(0, 0, 0); font-family: Helvetica; font-size: =
12px; font-style: normal; font-variant-caps: normal; font-weight: =
normal; letter-spacing: normal; text-align: start; text-indent: 0px; =
text-transform: none; white-space: normal; word-spacing: 0px; =
-webkit-text-stroke-width: 0px; text-decoration: none; float: none; =
display: inline !important;" class=3D"">stolj at<span =
class=3D"Apple-converted-space">&nbsp;</span></span><a =
href=3D"http://kannel.org/" style=3D"font-family: Helvetica; font-size: =
12px; font-style: normal; font-variant-caps: normal; font-weight: =
normal; letter-spacing: normal; orphans: auto; text-align: start; =
text-indent: 0px; text-transform: none; white-space: normal; widows: =
auto; word-spacing: 0px; -webkit-text-size-adjust: auto; =
-webkit-text-stroke-width: 0px;" class=3D"">kannel.org</a><span =
style=3D"caret-color: rgb(0, 0, 0); font-family: Helvetica; font-size: =
12px; font-style: normal; font-variant-caps: normal; font-weight: =
normal; letter-spacing: normal; text-align: start; text-indent: 0px; =
text-transform: none; white-space: normal; word-spacing: 0px; =
-webkit-text-stroke-width: 0px; text-decoration: none; float: none; =
display: inline !important;" class=3D""><span =
class=3D"Apple-converted-space">&nbsp;</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp=
;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;st at<span =
class=3D"Apple-converted-space">&nbsp;</span></span><a =
href=3D"http://tolj.org/" style=3D"font-family: Helvetica; font-size: =
12px; font-style: normal; font-variant-caps: normal; font-weight: =
normal; letter-spacing: normal; orphans: auto; text-align: start; =
text-indent: 0px; text-transform: none; white-space: normal; widows: =
auto; word-spacing: 0px; -webkit-text-size-adjust: auto; =
-webkit-text-stroke-width: 0px;" class=3D"">tolj.org</a><br =
style=3D"caret-color: rgb(0, 0, 0); font-family: Helvetica; font-size: =
12px; font-style: normal; font-variant-caps: normal; font-weight: =
normal; letter-spacing: normal; text-align: start; text-indent: 0px; =
text-transform: none; white-space: normal; word-spacing: 0px; =
-webkit-text-stroke-width: 0px; text-decoration: none;" class=3D""><span =
style=3D"caret-color: rgb(0, 0, 0); font-family: Helvetica; font-size: =
12px; font-style: normal; font-variant-caps: normal; font-weight: =
normal; letter-spacing: normal; text-align: start; text-indent: 0px; =
text-transform: none; white-space: normal; word-spacing: 0px; =
-webkit-text-stroke-width: 0px; text-decoration: none; float: none; =
display: inline !important;" =
class=3D"">---------------------------------------------------------------=
----</span><br style=3D"caret-color: rgb(0, 0, 0); font-family: =
Helvetica; font-size: 12px; font-style: normal; font-variant-caps: =
normal; font-weight: normal; letter-spacing: normal; text-align: start; =
text-indent: 0px; text-transform: none; white-space: normal; =
word-spacing: 0px; -webkit-text-stroke-width: 0px; text-decoration: =
none;" class=3D""><br style=3D"caret-color: rgb(0, 0, 0); font-family: =
Helvetica; font-size: 12px; font-style: normal; font-variant-caps: =
normal; font-weight: normal; letter-spacing: normal; text-align: start; =
text-indent: 0px; text-transform: none; white-space: normal; =
word-spacing: 0px; -webkit-text-stroke-width: 0px; text-decoration: =
none;" class=3D""><style class=3D"">ul[class*=3D'mb-extra__public-links'],=
 ul[class*=3D'mb-note__public-links'], =
ul[class*=3D'mb-task__public-links'] { display: none !important; =
}</style></div></blockquote></div><br class=3D""></div></body></html>=

--Apple-Mail=_16D4F14A-E7CF-45A5-A302-1AE1FB237AFF--