Skip to content

Commit bfa8dca

Browse files
committed
standby: pull once more after activation
Once we receive an activation request, pull once more to be up to date with the latest checkpoint in S3. If there is no newer checkpoint, the download should not take too long. Signed-off-by: Abhinav Gyawali <22275402+abhizer@users.noreply.github.com>
1 parent 16f6126 commit bfa8dca

4 files changed

Lines changed: 26 additions & 4 deletions

File tree

crates/adapters/src/controller/sync.rs

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -191,7 +191,13 @@ where
191191
}
192192

193193
let mut prev = uuid::Uuid::nil();
194-
while !is_activated() {
194+
let mut pull_once_again_after_activation = false;
195+
196+
// This should run at least once before checking for activation, to ensure
197+
// that we pull a checkpoint if one is available.
198+
// Also, if we receive an activation signal, we run one more iteration to
199+
// ensure that we have the latest checkpoint before activating.
200+
loop {
195201
match pull_and_gc(storage.backend.clone(), sync, &mut prev) {
196202
Err(err) => {
197203
if sync.fail_if_no_checkpoint {
@@ -207,6 +213,15 @@ where
207213
return Ok(());
208214
}
209215

216+
if is_activated() {
217+
if pull_once_again_after_activation {
218+
// We've already done one iteration after activation, now we're done
219+
break;
220+
}
221+
pull_once_again_after_activation = true;
222+
// Continue to pull one more time to get the latest checkpoint
223+
}
224+
210225
std::thread::sleep(std::time::Duration::from_secs(sync.pull_interval));
211226
}
212227

python/feldera/rest/_httprequests.py

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,8 @@ def send_request(
5656
"""
5757
self.headers["Content-Type"] = content_type
5858

59+
prev_resp: Optional[requests.Response] = None
60+
5961
try:
6062
conn_timeout = self.config.connection_timeout
6163
timeout = self.config.timeout
@@ -102,6 +104,8 @@ def send_request(
102104
verify=self.requests_verify,
103105
)
104106

107+
prev_resp = request
108+
105109
try:
106110
resp = self.__validate(request, stream=stream)
107111
logging.debug("got response: %s", str(resp))
@@ -134,6 +138,10 @@ def send_request(
134138
except requests.exceptions.ConnectionError as err:
135139
raise FelderaCommunicationError(str(err)) from err
136140

141+
raise FelderaAPIError(
142+
"Max retries exceeded, couldn't successfully connect to Feldera", prev_resp
143+
)
144+
137145
def get(
138146
self,
139147
path: str,

python/feldera/rest/feldera_client.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -185,7 +185,7 @@ def __wait_for_pipeline_state(
185185
elapsed = time.monotonic() - start_time
186186
if elapsed > timeout_s:
187187
raise TimeoutError(
188-
f"Timed out waiting for pipeline {pipeline_name} to"
188+
f"Timed out waiting for pipeline {pipeline_name} to "
189189
f"transition to '{state}' state"
190190
)
191191

python/tests/platform/test_checkpoint_sync.py

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -150,8 +150,7 @@ def test_checkpoint_sync(
150150

151151
if standby:
152152
assert self.pipeline.status() == PipelineStatus.STANDBY
153-
154-
self.pipeline.activate(timeout_s=10)
153+
self.pipeline.activate()
155154

156155
got_after = list(self.pipeline.query("SELECT * FROM v0"))
157156

0 commit comments

Comments
 (0)