Skip to content

Commit 2e38b84

Browse files
committed
create generator yielding function for sync project
1 parent 7dbed14 commit 2e38b84

File tree

2 files changed

+39
-16
lines changed

2 files changed

+39
-16
lines changed

mergin/cli.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -481,7 +481,7 @@ def sync(ctx):
481481
current_bar = None
482482
try:
483483
# Iterate over the generator to get updates
484-
for size_change, job in mc.sync_project(directory, upload_progress=True):
484+
for size_change, job in mc._sync_project_generator(directory):
485485
# Check if this is a new job (a new push operation)
486486
if job and job != current_job:
487487
# If a previous bar exists, close it

mergin/client.py

Lines changed: 38 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1512,7 +1512,42 @@ def create_invitation(self, workspace_id: int, email: str, workspace_role: Works
15121512
ws_inv = self.post(f"v2/workspaces/{workspace_id}/invitations", params, json_headers)
15131513
return json.load(ws_inv)
15141514

1515-
def sync_project(self, project_directory, upload_progress=False):
1515+
def _sync_project_generator(self, project_directory):
1516+
"""
1517+
See `sync_project` for details. This method is a generator yielding upload progress as (size_change, job) tuples.
1518+
1519+
:param project_directory: Project's directory
1520+
"""
1521+
mp = MerginProject(project_directory)
1522+
has_changes = True
1523+
server_conflict_attempts = 0
1524+
while has_changes:
1525+
self.pull_project(project_directory)
1526+
try:
1527+
job = push_project_async(self, project_directory)
1528+
if not job:
1529+
break
1530+
last_size = 0
1531+
while push_project_is_running(job):
1532+
sleep(SYNC_CALLBACK_WAIT)
1533+
current_size = job.transferred_size
1534+
yield (current_size - last_size, job) # Yields the size change and the job object
1535+
last_size = current_size
1536+
push_project_finalize(job)
1537+
_, has_changes = get_push_changes_batch(self, mp)
1538+
server_conflict_attempts = 0
1539+
except ClientError as e:
1540+
if e.is_retryable_sync() and server_conflict_attempts < PUSH_ATTEMPTS - 1:
1541+
# retry on conflict, e.g. when server has changes that we do not have yet
1542+
mp.log.info(
1543+
f"Restarting sync process (conflict on server) - {server_conflict_attempts + 1}/{PUSH_ATTEMPTS}"
1544+
)
1545+
server_conflict_attempts += 1
1546+
sleep(PUSH_ATTEMPT_WAIT)
1547+
continue
1548+
raise e
1549+
1550+
def sync_project(self, project_directory):
15161551
"""
15171552
Syncs project by loop with these steps:
15181553
1. Pull server version
@@ -1527,24 +1562,12 @@ def sync_project(self, project_directory, upload_progress=False):
15271562
has_changes = True
15281563
server_conflict_attempts = 0
15291564
while has_changes:
1530-
pull_job = pull_project_async(self, project_directory)
1531-
if pull_job:
1532-
pull_project_wait(pull_job)
1533-
pull_project_finalize(pull_job)
1534-
1565+
self.pull_project(project_directory)
15351566
try:
15361567
job = push_project_async(self, project_directory)
15371568
if not job:
15381569
break
1539-
if not upload_progress:
1540-
push_project_wait(job)
1541-
else:
1542-
last_size = 0
1543-
while push_project_is_running(job):
1544-
sleep(SYNC_CALLBACK_WAIT)
1545-
current_size = job.transferred_size
1546-
yield (current_size - last_size, job) # Yields the size change and the job object
1547-
last_size = current_size
1570+
push_project_wait(job)
15481571
push_project_finalize(job)
15491572
_, has_changes = get_push_changes_batch(self, mp)
15501573
server_conflict_attempts = 0

0 commit comments

Comments
 (0)