From 139641c6eae6446eff15864cf77801091ba3486d Mon Sep 17 00:00:00 2001 From: Peter Silva Date: Fri, 25 Oct 2024 15:52:58 -0400 Subject: [PATCH 01/12] updating examples for dd.weather to be ready for upcoming transition --- sarracenia/examples/subscribe/dd_2mqtt.conf | 4 ++++ sarracenia/examples/subscribe/dd_amis.conf | 4 ++++ sarracenia/examples/subscribe/dd_aqhi.conf | 4 ++++ sarracenia/examples/subscribe/dd_cacn_bulletins.conf | 4 ++++ sarracenia/examples/subscribe/dd_citypage.conf | 4 ++++ sarracenia/examples/subscribe/dd_cmml.conf | 4 ++++ sarracenia/examples/subscribe/dd_gdps.conf | 4 ++++ sarracenia/examples/subscribe/dd_radar.conf | 4 ++++ sarracenia/examples/subscribe/dd_rdps.conf | 4 ++++ sarracenia/examples/subscribe/dd_swob.conf | 5 +++++ 10 files changed, 41 insertions(+) diff --git a/sarracenia/examples/subscribe/dd_2mqtt.conf b/sarracenia/examples/subscribe/dd_2mqtt.conf index 7c9f4d4c3..baf3b28ff 100644 --- a/sarracenia/examples/subscribe/dd_2mqtt.conf +++ b/sarracenia/examples/subscribe/dd_2mqtt.conf @@ -15,4 +15,8 @@ post_exchange xpublic directory /tmp/dd_2mqt +# new topic... in 2025 +subtopic *.WXO-DD.bulletins.# + +# old topics likely replaced by above in 2025 subtopic bulletins.# diff --git a/sarracenia/examples/subscribe/dd_amis.conf b/sarracenia/examples/subscribe/dd_amis.conf index fb0cb466d..deb03ef0c 100644 --- a/sarracenia/examples/subscribe/dd_amis.conf +++ b/sarracenia/examples/subscribe/dd_amis.conf @@ -11,6 +11,10 @@ instances 5 # expire, in operational use, should be longer than longest expected interruption expire 10m +# new topic... in 2025 +subtopic *.WXO-DD.bulletins.alphanumeric.# + +# old topics likely replaced by above in 2025 subtopic bulletins.alphanumeric.# directory /tmp/dd_amis diff --git a/sarracenia/examples/subscribe/dd_aqhi.conf b/sarracenia/examples/subscribe/dd_aqhi.conf index 7aa8fede1..1e54471a3 100644 --- a/sarracenia/examples/subscribe/dd_aqhi.conf +++ b/sarracenia/examples/subscribe/dd_aqhi.conf @@ -18,6 +18,10 @@ instances 2 # valeur basse bonne pour essais initial, valeur haute (1d == 1 jour) pour les opérations. expire 10m +# new topic... in 2025 +subtopic *.WXO-DD.air_quality.aqhi.# + +# old topics likely replaced by above in 2025 subtopic air_quality.aqhi.# directory /tmp/dd_aqhi diff --git a/sarracenia/examples/subscribe/dd_cacn_bulletins.conf b/sarracenia/examples/subscribe/dd_cacn_bulletins.conf index 2da93a120..5a6422950 100644 --- a/sarracenia/examples/subscribe/dd_cacn_bulletins.conf +++ b/sarracenia/examples/subscribe/dd_cacn_bulletins.conf @@ -19,6 +19,10 @@ instances 2 expire 10m +# new topic... in 2025 +subtopic *.WXO-DD.bulletins.alphanumeric.*.CA.*.# + +# old topics likely replaced by above in 2025 subtopic bulletins.alphanumeric.*.CA.*.# directory /tmp/cacn_bulletins accept .*CACN45.* diff --git a/sarracenia/examples/subscribe/dd_citypage.conf b/sarracenia/examples/subscribe/dd_citypage.conf index 412b86bad..a29edb21e 100644 --- a/sarracenia/examples/subscribe/dd_citypage.conf +++ b/sarracenia/examples/subscribe/dd_citypage.conf @@ -18,6 +18,10 @@ instances 2 # durée de vie du file d´attente sur le serveur. Pour usage opérationnel, augmentez a 1d (1 jour.) expire 10m +# new topic... in 2025 +subtopic *.WXO-DD.citypage_weather.# + +# old topics likely replaced by above in 2025 subtopic citypage_weather.# #subtopic citypage_weather.xml.YT.# diff --git a/sarracenia/examples/subscribe/dd_cmml.conf b/sarracenia/examples/subscribe/dd_cmml.conf index aed3018b9..17be6b039 100644 --- a/sarracenia/examples/subscribe/dd_cmml.conf +++ b/sarracenia/examples/subscribe/dd_cmml.conf @@ -21,6 +21,10 @@ instances 2 # le file est enlevé. expire 10m +# new topic... in 2025 +subtopic *.WXO-DD.meteocode.*.cmml.# + +# old topics likely replaced by above in 2025 subtopic meteocode.*.cmml.# directory /tmp/dd_cmml diff --git a/sarracenia/examples/subscribe/dd_gdps.conf b/sarracenia/examples/subscribe/dd_gdps.conf index 0afbc46c1..c11801104 100644 --- a/sarracenia/examples/subscribe/dd_gdps.conf +++ b/sarracenia/examples/subscribe/dd_gdps.conf @@ -24,5 +24,9 @@ instances 5 expire 10m #expire, in operational use, use 1d (1 day) as it needs to be longer than the longest interruption in downloads we want to tolerate without dropping downloads. +# new topic... in 2025 +subtopic *.WXO-DD.model_gem_global.25km.grib2.# + +# old topics likely replaced by above in 2025 subtopic model_gem_global.25km.grib2.# directory /tmp/dd_gdps diff --git a/sarracenia/examples/subscribe/dd_radar.conf b/sarracenia/examples/subscribe/dd_radar.conf index 0dc7d3af8..5c89e99c2 100644 --- a/sarracenia/examples/subscribe/dd_radar.conf +++ b/sarracenia/examples/subscribe/dd_radar.conf @@ -24,4 +24,8 @@ expire 10m directory /tmp/dd_radar +# new topic... in 2025 +subtopic *.WXO-DD.radar.CAPPI.GIF.XAM.# + +# old topics likely replaced by above in 2025 subtopic radar.CAPPI.GIF.XAM.# diff --git a/sarracenia/examples/subscribe/dd_rdps.conf b/sarracenia/examples/subscribe/dd_rdps.conf index 9bb845135..829f36982 100644 --- a/sarracenia/examples/subscribe/dd_rdps.conf +++ b/sarracenia/examples/subscribe/dd_rdps.conf @@ -25,5 +25,9 @@ expire 10m # suggest 1d (1 day.) +# new topic... in 2025 +subtopic *.WXO-DD.model_gem_regional.10km.grib2.# + +# old topics likely replaced by above in 2025 subtopic model_gem_regional.10km.grib2.# director /tmp/dd_rdps diff --git a/sarracenia/examples/subscribe/dd_swob.conf b/sarracenia/examples/subscribe/dd_swob.conf index 8789f236c..d5778f04f 100644 --- a/sarracenia/examples/subscribe/dd_swob.conf +++ b/sarracenia/examples/subscribe/dd_swob.conf @@ -21,6 +21,11 @@ expire 10m #expire, in operations, needs to be longer than the longest expected interruption # All stations + +# new topic... in 2025 +subtopic *.WXO-DD.observations.swob-ml.# + +# old topics likely replaced by above in 2025 subtopic observations.swob-ml.# directory /tmp/dd_swob From c5149c730b9509020e38f59ec9e208052588c735 Mon Sep 17 00:00:00 2001 From: Andre LeBlanc Date: Mon, 28 Oct 2024 16:38:24 +0000 Subject: [PATCH 02/12] Fixes after testing with other components on dev #1271 --- sarracenia/bulletin.py | 8 +++++--- sarracenia/flowcb/gather/am.py | 2 +- sarracenia/flowcb/rename/raw2bulletin.py | 22 ++++++++++++++-------- 3 files changed, 20 insertions(+), 12 deletions(-) diff --git a/sarracenia/bulletin.py b/sarracenia/bulletin.py index 6e2b3b0a0..fc461f5a1 100644 --- a/sarracenia/bulletin.py +++ b/sarracenia/bulletin.py @@ -23,7 +23,9 @@ class Bulletin: from sarracenia.bulletin import Bulletin """ - def __init__(self): + def __init__(self,options): + super().__init__() + self.o = options self.seq = 0 self.binary = 0 @@ -125,7 +127,7 @@ def getData(self, msg, path): try: self.binary = 0 - if msg['content']: + if 'content' in msg: data = msg['content']['value'] # Change from b64. We want to get the header from the raw binary data. Not retrievable in b64 format @@ -339,4 +341,4 @@ def getTime(self, data): ddHHMM = time.strftime('%d%H%M', timeStruct) return ddHHMM except Exception as e: - return None \ No newline at end of file + return None diff --git a/sarracenia/flowcb/gather/am.py b/sarracenia/flowcb/gather/am.py index ae6f48808..e615fc38f 100644 --- a/sarracenia/flowcb/gather/am.py +++ b/sarracenia/flowcb/gather/am.py @@ -78,7 +78,7 @@ class Am(FlowCB): def __init__(self, options): super().__init__(options,logger) - self.bulletinHandler = Bulletin() + self.bulletinHandler = Bulletin(self.o) self.url = urllib.parse.urlparse(self.o.sendTo) diff --git a/sarracenia/flowcb/rename/raw2bulletin.py b/sarracenia/flowcb/rename/raw2bulletin.py index 6a8d73d18..054994470 100644 --- a/sarracenia/flowcb/rename/raw2bulletin.py +++ b/sarracenia/flowcb/rename/raw2bulletin.py @@ -76,7 +76,7 @@ def __init__(self,options) : super().__init__(options,logger) self.seq = 0 self.binary = 0 - self.bulletinHandler = Bulletin() + self.bulletinHandler = Bulletin(self.o) # Need to redeclare these options to have their default values be initialized. self.o.add_option('inputCharset', 'str', 'utf-8') self.o.add_option('binaryInitialCharacters', 'list', [b'BUFR' , b'GRIB', b'\211PNG']) @@ -87,7 +87,9 @@ def after_accept(self,worklist): new_worklist = [] for msg in worklist.incoming: - path = msg['new_dir'] + '/' + msg['new_file'] + + # If called by a sarra, should always have post_baseDir, so should be OK in specifying it + path = self.o.post_baseDir + '/' + msg['relPath'] data = self.bulletinHandler.getData(msg, path) @@ -133,13 +135,16 @@ def after_accept(self,worklist): # Generate a sequence (random ints) seq = self.bulletinHandler.getSequence() - + # Assign a default value for messages not coming from AM + if 'isProblem' not in msg: + msg['isProblem'] = False + # Rename file with data fetched try: # We can't disseminate bulletins downstream if they're missing the timestamp, but we want to keep the bulletins to troubleshoot source problems # We'll append "_PROBLEM" to the filename to be able to identify erronous bulletins - if ddhhmm == None or msg["isProblem"]: + if ddhhmm == None or msg['isProblem']: timehandler = datetime.datetime.now() # Add current time as new timestamp to filename @@ -162,11 +167,12 @@ def after_accept(self,worklist): new_file = header + "_" + ddhhmm + "_" + BBB + "_" + stn_id + "_" + seq msg['new_file'] = new_file - # We need the rest of the fields to be also updated - del(msg['relPath']) + # No longer needed - del(msg['isProblem']) - msg.updatePaths(self.o, msg['new_dir'], msg['new_file']) + if 'isProblem' in msg: + del(msg['isProblem']) + + # msg.updatePaths(self.o, msg['new_dir'], msg['new_file']) logger.info(f"New filename (with path): {msg['relPath']}") new_worklist.append(msg) From c2ae779a0f716ff0b5ddd83613fad9bfb6ed2470 Mon Sep 17 00:00:00 2001 From: Andre LeBlanc Date: Mon, 28 Oct 2024 16:44:23 +0000 Subject: [PATCH 03/12] Add better log message --- sarracenia/flowcb/rename/raw2bulletin.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sarracenia/flowcb/rename/raw2bulletin.py b/sarracenia/flowcb/rename/raw2bulletin.py index 054994470..585be0208 100644 --- a/sarracenia/flowcb/rename/raw2bulletin.py +++ b/sarracenia/flowcb/rename/raw2bulletin.py @@ -174,7 +174,7 @@ def after_accept(self,worklist): # msg.updatePaths(self.o, msg['new_dir'], msg['new_file']) - logger.info(f"New filename (with path): {msg['relPath']}") + logger.info(f"New filename: {msg['new_file']}") new_worklist.append(msg) except Exception as e: From 95f77aa01c553236746d1bf5d3c95ec070ad409e Mon Sep 17 00:00:00 2001 From: Peter Silva Date: Mon, 28 Oct 2024 14:37:36 -0400 Subject: [PATCH 04/12] missing file name in configuration warning message --- sarracenia/config/__init__.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sarracenia/config/__init__.py b/sarracenia/config/__init__.py index 05f7fcffd..d14bdee20 100755 --- a/sarracenia/config/__init__.py +++ b/sarracenia/config/__init__.py @@ -1761,7 +1761,7 @@ def parse_line(self, component, cfg, cfname, lineno, l ): # specify a second queue with different bindings... so this warning could be complaining about something # that is correct. but in every current case, the warning will be helpful. if ( k == 'queueName' ) and self.subtopic_seen: - logger.warning( f"queueName usually should be before subtopic in configs: subtopic to default queue" ) + logger.warning( f"{','.join(self.files)}:{lineno} queueName usually should be before subtopic in configs: subtopic to default queue" ) if ( k == 'directory' ) and not self.download: logger.info( f"{','.join(self.files)}:{lineno} if download is false, directory has no effect" ) From 29da76f204d86a86f2af25475ef0b76c652cd471 Mon Sep 17 00:00:00 2001 From: Andre LeBlanc Date: Tue, 29 Oct 2024 12:29:31 +0000 Subject: [PATCH 05/12] Add post_baseDir to unit tests #1271 --- tests/sarracenia/flowcb/gather/am__gather_test.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/tests/sarracenia/flowcb/gather/am__gather_test.py b/tests/sarracenia/flowcb/gather/am__gather_test.py index 17c51aeae..7f7981016 100755 --- a/tests/sarracenia/flowcb/gather/am__gather_test.py +++ b/tests/sarracenia/flowcb/gather/am__gather_test.py @@ -25,6 +25,7 @@ def __init__(self): self.fileAgeMax = 0 self.post_baseUrl = "http://localhost/" self.post_format = "v02" + self.post_baseDir = "/this/path/is/fake" def add_option(self, option, type, default = None): if not hasattr(self, option): @@ -49,6 +50,7 @@ def make_message(): m["to_clusters"] = "localhost" m["baseUrl"] = "https://NotARealURL" m["post_baseUrl"] = "https://NotARealURL" + m["post_baseDir"] = "/this/path/is/fake" m["relPath"] = "ThisIsAPath/To/A/File.txt" m["_deleteOnPost"] = set() return m From 8f7cdce40490a38e53b0532f2a5d1d0da89837ce Mon Sep 17 00:00:00 2001 From: Andre LeBlanc Date: Tue, 29 Oct 2024 14:35:50 +0000 Subject: [PATCH 06/12] Change getData to getContent msg function. Make code more uniform #1271 --- sarracenia/flowcb/rename/raw2bulletin.py | 19 +++++++++++-------- 1 file changed, 11 insertions(+), 8 deletions(-) diff --git a/sarracenia/flowcb/rename/raw2bulletin.py b/sarracenia/flowcb/rename/raw2bulletin.py index 585be0208..3665e4076 100644 --- a/sarracenia/flowcb/rename/raw2bulletin.py +++ b/sarracenia/flowcb/rename/raw2bulletin.py @@ -91,16 +91,19 @@ def after_accept(self,worklist): # If called by a sarra, should always have post_baseDir, so should be OK in specifying it path = self.o.post_baseDir + '/' + msg['relPath'] - data = self.bulletinHandler.getData(msg, path) + data = msg.getContent() + + # Determine if bulletin is binary or not + # From sundew source code + if data.splitlines()[1][:4] in self.o.binaryInitialCharacters: + # Decode data, only text. The raw binary data contains the header in which we're interested. Only get that header. + data = data.splitlines()[0].decode('ascii') + else: + # Data is not binary + data = data.decode('utf-8') - # AM bulletins that need their filename rewritten with data should only have two chars before the first underscore - # This is in concordance with Sundew logic -> https://github.com/MetPX/Sundew/blob/main/lib/bulletinAm.py#L70-L71 - # These messages are still good, so we will add them to the good_msgs list - # if len(filenameFirstChars) != 2 and self.binary: - # good_msgs.append(msg) - # continue - if data == None: + if not data: logger.error("No data was found. Skipping message") worklist.rejected.append(msg) continue From 1acd313e58c7a79c43370b0092c9b788d2acfde2 Mon Sep 17 00:00:00 2001 From: Andre LeBlanc Date: Tue, 29 Oct 2024 15:47:53 +0000 Subject: [PATCH 07/12] Integrate inputCharset. Need iso-8859-1 for french chars #1271 --- sarracenia/__init__.py | 3 ++- sarracenia/flowcb/rename/raw2bulletin.py | 4 ++-- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/sarracenia/__init__.py b/sarracenia/__init__.py index a2797165c..3de6b7661 100755 --- a/sarracenia/__init__.py +++ b/sarracenia/__init__.py @@ -1019,10 +1019,11 @@ def getContent(msg,options=None): # inlined/embedded case. if 'content' in msg: + logger.info("Getting msg from inline'd content") if msg['content']['encoding'] == 'base64': return b64decode(msg['content']['value']) else: - return msg['content']['value'].encode('utf-8') + return msg['content']['value'].encode('utf-8') if not options.inputCharset else msg['content']['value'].encode(options.inputCharset) path='' if msg['baseUrl'].startswith('file:'): diff --git a/sarracenia/flowcb/rename/raw2bulletin.py b/sarracenia/flowcb/rename/raw2bulletin.py index 3665e4076..6d8c8a115 100644 --- a/sarracenia/flowcb/rename/raw2bulletin.py +++ b/sarracenia/flowcb/rename/raw2bulletin.py @@ -91,7 +91,7 @@ def after_accept(self,worklist): # If called by a sarra, should always have post_baseDir, so should be OK in specifying it path = self.o.post_baseDir + '/' + msg['relPath'] - data = msg.getContent() + data = msg.getContent(self.o) # Determine if bulletin is binary or not # From sundew source code @@ -100,7 +100,7 @@ def after_accept(self,worklist): data = data.splitlines()[0].decode('ascii') else: # Data is not binary - data = data.decode('utf-8') + data = data.decode(self.o.inputCharset) if not data: From 5d6086c837c7e20d5ef5fbb77d4871b4553f4f3f Mon Sep 17 00:00:00 2001 From: Andre LeBlanc Date: Tue, 29 Oct 2024 16:05:20 +0000 Subject: [PATCH 08/12] Should be checking with hasattr #1271 --- sarracenia/__init__.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sarracenia/__init__.py b/sarracenia/__init__.py index 3de6b7661..f0c8b64da 100755 --- a/sarracenia/__init__.py +++ b/sarracenia/__init__.py @@ -1023,7 +1023,7 @@ def getContent(msg,options=None): if msg['content']['encoding'] == 'base64': return b64decode(msg['content']['value']) else: - return msg['content']['value'].encode('utf-8') if not options.inputCharset else msg['content']['value'].encode(options.inputCharset) + return msg['content']['value'].encode('utf-8') if not hasattr(options,'inputCharset') else msg['content']['value'].encode(options.inputCharset) path='' if msg['baseUrl'].startswith('file:'): From 179f8a2b4d0c068ad7bb4710767e29e1d94d9fdb Mon Sep 17 00:00:00 2001 From: Peter Silva Date: Tue, 29 Oct 2024 16:35:12 -0400 Subject: [PATCH 09/12] close #1278 we learned that acks should never be retried --- sarracenia/moth/amqp.py | 12 +++++------- 1 file changed, 5 insertions(+), 7 deletions(-) diff --git a/sarracenia/moth/amqp.py b/sarracenia/moth/amqp.py index 69049a85f..9a51db4a8 100755 --- a/sarracenia/moth/amqp.py +++ b/sarracenia/moth/amqp.py @@ -603,13 +603,11 @@ def ack(self, m: sarracenia.Message) -> None: except Exception as err: logger.warning("failed for tag: %s: %s" % (m['ack_id'], err)) logger.debug('Exception details: ', exc_info=True) - if type(err) == BrokenPipeError or type(err) == ConnectionResetError: - # Cleanly close partially broken connection - self.close() - # No point in trying to ack again if the connection is broken - del m['ack_id'] - m['_deleteOnPost'].remove('ack_id') - return False + # No point in trying to ack again if the connection is broken + del m['ack_id'] + m['_deleteOnPost'].remove('ack_id') + self.close() + return False if ebo < 60: ebo *= 2 From af41050de19fceb7bc0f947e737d07c56ecd406e Mon Sep 17 00:00:00 2001 From: Mathew Shaker Date: Tue, 29 Oct 2024 21:05:02 +0000 Subject: [PATCH 10/12] Add check for any disabled configs when using sr3 start --- sarracenia/sr.py | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/sarracenia/sr.py b/sarracenia/sr.py index 6a3109364..93a3b9372 100755 --- a/sarracenia/sr.py +++ b/sarracenia/sr.py @@ -2233,6 +2233,20 @@ def start(self): if len(self.leftovers) > 0 and not self._action_all_configs: logging.error( f"{self.leftovers} configuration not found" ) return + + has_disabled_config = False + + # if any configs are disabled, don't start any + for f in self.filtered_configurations: + (c, cfg) = f.split(os.sep) + + if self.configs[c][cfg]['status'] == 'disabled': + has_disabled_config = True + logger.error(f"Config {c}/{cfg} is disabled. It must be enabled before starting.") + + if has_disabled_config: + logger.error("No configs have been started due to disabled configurations.") + return pcount = 0 for f in self.filtered_configurations: From 3802fe384ba563a8cd38c6fd54c461eb64de5752 Mon Sep 17 00:00:00 2001 From: Peter Silva Date: Wed, 30 Oct 2024 11:19:37 -0400 Subject: [PATCH 11/12] slight adjustment to disable check for when no configs specified --- sarracenia/sr.py | 17 +++++++++-------- 1 file changed, 9 insertions(+), 8 deletions(-) diff --git a/sarracenia/sr.py b/sarracenia/sr.py index 93a3b9372..1504d7576 100755 --- a/sarracenia/sr.py +++ b/sarracenia/sr.py @@ -2237,16 +2237,17 @@ def start(self): has_disabled_config = False # if any configs are disabled, don't start any - for f in self.filtered_configurations: - (c, cfg) = f.split(os.sep) + if not self._action_all_configs: + for f in self.filtered_configurations: + (c, cfg) = f.split(os.sep) - if self.configs[c][cfg]['status'] == 'disabled': - has_disabled_config = True - logger.error(f"Config {c}/{cfg} is disabled. It must be enabled before starting.") + if self.configs[c][cfg]['status'] == 'disabled': + has_disabled_config = True + logger.error(f"Config {c}/{cfg} is disabled. It must be enabled before starting.") - if has_disabled_config: - logger.error("No configs have been started due to disabled configurations.") - return + if has_disabled_config: + logger.error("No configs have been started due to disabled configurations.") + return pcount = 0 for f in self.filtered_configurations: From 3d49841483129c590de6fd31f34b54c1c4f3780a Mon Sep 17 00:00:00 2001 From: Peter Silva Date: Wed, 30 Oct 2024 12:31:20 -0400 Subject: [PATCH 12/12] release v3.00.56rc3 --- debian/changelog | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/debian/changelog b/debian/changelog index 69edaaafa..0753e135b 100644 --- a/debian/changelog +++ b/debian/changelog @@ -1,3 +1,11 @@ +metpx-sr3 (3.00.56rc3) unstable; urgency=medium + + * fix #1278 regression: ack failure loops forever. + * fix #1271 AM charset issues, made some plugins more flexible. + * fix #1266 complain when explicitly asked to start disabled config. + + -- SSC-5CD2310S60 Wed, 30 Oct 2024 12:25:14 -0400 + metpx-sr3 (3.00.56rc2) unstable; urgency=medium * fix #1261 http performance regression.