Changeset 3799472
- Timestamp:
- 11/13/2026 12:28:48 AM (less than one hour ago)
- Location:
- bmlt-workflow/trunk
- Files:
-
- 5 edited
-
CHANGELOG.md (modified) (1 diff)
-
bmlt-workflow.php (modified) (8 diffs)
-
readme.txt (modified) (1 diff)
-
src/BMLT/Integration.php (modified) (4 diffs)
-
src/REST/Handlers/BMLTServerHandler.php (modified) (1 diff)
Legend:
- Unmodified
- Added
- Removed
-
bmlt-workflow/trunk/CHANGELOG.md
r3777421 r3799472 1 ## 1.2.4 (November 12, 2026) 2 - #239 Fixes the whole site slowing to ~35-40s per page (and fatal errors on form pages) when the configured BMLT Root Server is slow or unreachable: server info lookups now use a short 5s timeout, failures are briefly cached so an unreachable server no longer triggers a blocking network call on every page load, REST request and 404, and the version lookup is no longer made during plugin bootstrap on every request. 3 - The meeting update form now shows an inline error notice instead of a fatal `wp_die()` when the BMLT server can't be reached, so the rest of the page still renders. 4 1 5 ## 1.2.3 (October 31, 2026) 2 6 - Fixes approving a change to a meeting that has coordinates but no timezone; the timezone is now resolved from the meeting's existing coordinates via the geo service. -
bmlt-workflow/trunk/bmlt-workflow.php
r3777421 r3799472 21 21 * Plugin URI: https://github.com/bmlt-enabled/bmlt-workflow 22 22 * Description: Workflows for BMLT meeting management! 23 * Version: 1.2. 323 * Version: 1.2.4 24 24 * Requires at least: 5.2 25 25 * Author: @nigel-bmlt … … 30 30 31 31 32 define('BMLTWF_PLUGIN_VERSION', '1.2. 3');32 define('BMLTWF_PLUGIN_VERSION', '1.2.4'); 33 33 34 34 if ((!defined('ABSPATH') && (!defined('BMLTWF_RUNNING_UNDER_PHPUNIT')))) exit; // die if being called directly … … 170 170 } 171 171 172 /** 173 * Render a non-fatal error notice for a shortcode. 174 * 175 * Returned (not wp_die'd) so the surrounding page - theme, header, 176 * footer and any other content - still renders when the BMLT server is 177 * unreachable or misconfigured. 178 * 179 * @param string $message Human-readable error detail. 180 * @return string 181 */ 182 private function bmltwf_form_error($message) 183 { 184 return '<div class="bmltwf-error-notice" style="padding:1em;border:1px solid #c00;background:#fff3f3;color:#900;">' 185 . '<strong>' . esc_html__('BMLT Workflow Plugin Error', 'bmlt-workflow') . ':</strong> ' 186 . esc_html($message) 187 . '</div>'; 188 } 189 172 190 public function bmltwf_meeting_update_form($atts = [], $content = null, $tag = '') 173 191 { … … 175 193 $bmltwf_bmlt_test_status = get_option('bmltwf_bmlt_test_status', "failure"); 176 194 if ($bmltwf_bmlt_test_status != "success") { 177 wp_die("<h4>BMLTWF Plugin Error: BMLT Root Server not configured and tested.</h4>");195 return $this->bmltwf_form_error(__('BMLT Root Server not configured and tested.', 'bmlt-workflow')); 178 196 } 179 197 // $this->debug_log(("inside shortcode setup")); … … 207 225 $meeting_counties_and_sub_provinces = $this->bmlt_integration->getMeetingCounties(); 208 226 if (is_wp_error($meeting_counties_and_sub_provinces)) { 209 wp_die("<h4>" . __('BMLTWF Plugin Error: Unable to retrieve meeting counties from BMLT server.', 'bmlt-workflow') . "</h4>");227 return $this->bmltwf_form_error(__('Unable to retrieve meeting counties from BMLT server.', 'bmlt-workflow')); 210 228 } 211 229 $script .= "var bmltwf_counties_and_sub_provinces = " . json_encode($meeting_counties_and_sub_provinces) . ";"; … … 218 236 $meeting_states_and_provinces = $this->bmlt_integration->getMeetingStates(); 219 237 if (is_wp_error($meeting_states_and_provinces)) { 220 wp_die("<h4>" . __('BMLTWF Plugin Error: Unable to retrieve meeting states/provinces from BMLT server.', 'bmlt-workflow') . "</h4>");238 return $this->bmltwf_form_error(__('Unable to retrieve meeting states/provinces from BMLT server.', 'bmlt-workflow')); 221 239 } 222 240 $script .= "var bmltwf_do_states_and_provinces = " . json_encode($meeting_states_and_provinces) . ";"; … … 229 247 $formatarr = $this->bmlt_integration->getMeetingFormats(); 230 248 if (is_wp_error($formatarr)) { 231 wp_die("<h4>" . __('BMLTWF Plugin Error: Unable to retrieve meeting formats from BMLT server.', 'bmlt-workflow') . "</h4>");249 return $this->bmltwf_form_error(__('Unable to retrieve meeting formats from BMLT server.', 'bmlt-workflow')); 232 250 } 233 251 … … 245 263 $result = rest_get_server()->response_to_data($response, true); 246 264 if (count($result) == 0) { 247 wp_die("<h4>BMLT Workflow Plugin Error: Service bodies not configured.</h4>");265 return $this->bmltwf_form_error(__('Service bodies not configured.', 'bmlt-workflow')); 248 266 } 249 267 $script .= 'var bmltwf_service_bodies = ' . json_encode($result) . '; '; -
bmlt-workflow/trunk/readme.txt
r3777421 r3799472 5 5 Requires PHP: 8.0 6 6 License: GPLv2 7 Stable tag: 1.2. 37 Stable tag: 1.2.4 8 8 Contributors: nigelbmlt, pjaudiomv 9 9 -
bmlt-workflow/trunk/src/BMLT/Integration.php
r3777421 r3799472 114 114 } 115 115 116 if (empty($root_server_version)) { 117 $server_address = \get_option('bmltwf_bmlt_server_address'); 118 if ($server_address && $server_address !== 'true' && filter_var($server_address, FILTER_VALIDATE_URL)) { 119 $this->bmlt_root_server_version = $this->bmltwf_get_remote_server_version($server_address); 120 } 121 } else { 116 if (!empty($root_server_version)) { 122 117 $this->bmlt_root_server_version = $root_server_version; 123 118 } 119 // Otherwise resolve the version lazily via getRootServerVersion(). This 120 // class is constructed during plugin bootstrap on every request, so 121 // fetching the version here used to make a blocking HTTP call to the 122 // BMLT server on every page load - taking the whole site down when that 123 // server was slow or unreachable. 124 124 } 125 125 … … 143 143 } 144 144 145 /** 146 * Lazily resolve and cache the BMLT root server version. 147 * 148 * @return string|false|null 149 */ 150 public function getRootServerVersion() 151 { 152 if ($this->bmlt_root_server_version === null) { 153 $server_address = \get_option('bmltwf_bmlt_server_address'); 154 if ($server_address && $server_address !== 'true' && filter_var($server_address, FILTER_VALIDATE_URL)) { 155 $this->bmlt_root_server_version = $this->bmltwf_get_remote_server_version($server_address); 156 } 157 } 158 return $this->bmlt_root_server_version; 159 } 160 145 161 public function update_root_server_version() 146 162 { 147 163 $server_address = \get_option('bmltwf_bmlt_server_address'); 148 // Clear the cache to force a fresh fetch164 // Clear the cache (and any negative-cache marker) to force a fresh fetch 149 165 \delete_transient('bmltwf_server_info_' . md5($server_address)); 166 \delete_transient('bmltwf_server_info_fail_' . md5($server_address)); 150 167 $new_version = $this->bmltwf_get_remote_server_version($server_address); 151 168 $this->bmlt_root_server_version = $new_version; … … 178 195 private function bmltwf_get_server_info_cached($server) 179 196 { 197 if (empty($server)) { 198 return false; 199 } 200 180 201 $cache_key = 'bmltwf_server_info_' . md5($server); 181 202 $fail_key = 'bmltwf_server_info_fail_' . md5($server); 203 182 204 // Skip cache if nocache parameter is present 183 205 $use_cache = !isset($_GET['nocache']); 184 206 185 207 if ($use_cache) { 186 208 $cached = \get_transient($cache_key); … … 188 210 return $cached; 189 211 } 190 } 191 212 // Negative cache: if we recently failed to reach the server, don't 213 // block this request on another (likely slow) network call. This 214 // prevents an unreachable/slow BMLT server from stalling every page 215 // load, REST request and 404. 216 if (\get_transient($fail_key) !== false) { 217 return false; 218 } 219 } 220 192 221 $url = $server . "client_interface/json/?switcher=GetServerInfo"; 193 222 $headers = array("Accept: */*"); 194 $resp = $this->bmltwf_wp_remote_get($url, array('headers' => $headers)); 195 223 // Use a short, explicit timeout so a slow server fails fast rather than 224 // hanging on WP's default timeout and stacking across multiple calls. 225 $resp = $this->bmltwf_wp_remote_get($url, array('headers' => $headers, 'timeout' => 5)); 226 196 227 if (is_wp_error($resp) || \wp_remote_retrieve_response_code($resp) != 200) { 228 if ($use_cache) { 229 \set_transient($fail_key, 1, 60); 230 } 197 231 return false; 198 232 } 199 233 200 234 $data = json_decode(\wp_remote_retrieve_body($resp), true); 201 235 if ($data === null || !isset($data[0])) { 236 if ($use_cache) { 237 \set_transient($fail_key, 1, 60); 238 } 202 239 return false; 203 240 } 204 241 205 242 // Cache for 1 hour (3600 seconds) if caching is enabled 206 243 if ($use_cache) { 244 \delete_transient($fail_key); 207 245 \set_transient($cache_key, $data[0], 3600); 208 246 } 209 247 210 248 return $data[0]; 211 249 } -
bmlt-workflow/trunk/src/REST/Handlers/BMLTServerHandler.php
r3765048 r3799472 111 111 if ($current_server !== $server) { 112 112 \delete_transient('bmltwf_server_info_' . md5($server)); 113 \delete_transient('bmltwf_server_info_fail_' . md5($server)); 113 114 } 114 115
Note:
See TracChangeset
for help on using the changeset viewer.