Skip to content

Commit 9fa6c04

Browse files
committed
Split push for blocking and non-blocking
1 parent d8bc3e7 commit 9fa6c04

File tree

6 files changed

+68
-27
lines changed

6 files changed

+68
-27
lines changed

README.md

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -81,9 +81,9 @@ Commands:
8181
share Fetch permissions to project
8282
share-add Add permissions to [users] to project
8383
share-remove Remove [users] permissions from project
84-
show-file-changeset Displays information about project changes.
85-
show-file-history Displays information about a single version of a...
86-
show-version Displays information about a single version of a...
84+
show-file-changeset Display information about project changes.
85+
show-file-history Display information about a single version of a...
86+
show-version Display information about a single version of a...
8787
status Show all changes in project files - upstream and...
8888
```
8989

@@ -99,7 +99,7 @@ To download a specific version of a project:
9999
$ mergin --username john download --version v42 john/project1 ~/mergin/project1
100100
```
101101

102-
To download a sepecific version of a single file:
102+
To download a specific version of a single file:
103103

104104
1. First you need to download the project:
105105
```

mergin/cli.py

Lines changed: 15 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -412,17 +412,18 @@ def push(ctx):
412412
return
413413
directory = os.getcwd()
414414
try:
415-
job = push_project_async(mc, directory)
416-
if job is not None: # if job is none, we don't upload any files, and the transaction is finished already
417-
with click.progressbar(length=job.total_size) as bar:
418-
last_transferred_size = 0
419-
while push_project_is_running(job):
420-
time.sleep(1 / 10) # 100ms
421-
new_transferred_size = job.transferred_size
422-
bar.update(new_transferred_size - last_transferred_size) # the update() needs increment only
423-
last_transferred_size = new_transferred_size
424-
push_project_finalize(job)
425-
click.echo("Done")
415+
blocking_job, non_blocking_job = push_project_async(mc, directory)
416+
for job in [blocking_job, non_blocking_job]:
417+
if job is not None: # if job is none, we don't upload any files, and the transaction is finished already
418+
with click.progressbar(length=job.total_size) as bar:
419+
last_transferred_size = 0
420+
while push_project_is_running(job):
421+
time.sleep(1 / 10) # 100ms
422+
new_transferred_size = job.transferred_size
423+
bar.update(new_transferred_size - last_transferred_size) # the update() needs increment only
424+
last_transferred_size = new_transferred_size
425+
push_project_finalize(job)
426+
click.echo("Done")
426427
except InvalidProject as e:
427428
click.secho("Invalid project directory ({})".format(str(e)), fg="red")
428429
except ClientError as e:
@@ -473,7 +474,7 @@ def pull(ctx):
473474
@click.argument("version")
474475
@click.pass_context
475476
def show_version(ctx, version):
476-
"""Displays information about a single version of a project. `version` is 'v1', 'v2', etc."""
477+
"""Display information about a single version of a project. `version` is 'v1', 'v2', etc."""
477478
mc = ctx.obj["client"]
478479
if mc is None:
479480
return
@@ -492,7 +493,7 @@ def show_version(ctx, version):
492493
@click.argument("path")
493494
@click.pass_context
494495
def show_file_history(ctx, path):
495-
"""Displays information about a single version of a project."""
496+
"""Display information about a single version of a project."""
496497
mc = ctx.obj["client"]
497498
if mc is None:
498499
return
@@ -516,7 +517,7 @@ def show_file_history(ctx, path):
516517
@click.argument("version")
517518
@click.pass_context
518519
def show_file_changeset(ctx, path, version):
519-
"""Displays information about project changes."""
520+
"""Display information about project changes."""
520521
mc = ctx.obj["client"]
521522
if mc is None:
522523
return

mergin/client.py

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -876,11 +876,12 @@ def push_project(self, directory):
876876
:param directory: Project's directory
877877
:type directory: String
878878
"""
879-
job = push_project_async(self, directory)
880-
if job is None:
881-
return # there is nothing to push (or we only deleted some files)
882-
push_project_wait(job)
883-
push_project_finalize(job)
879+
blocking_job, non_blocking_job = push_project_async(self, directory)
880+
for job in [blocking_job, non_blocking_job]:
881+
if job is None:
882+
return # there is nothing to push (or we only deleted some files)
883+
push_project_wait(job)
884+
push_project_finalize(job)
884885

885886
def pull_project(self, directory):
886887
"""

mergin/client_push.py

Lines changed: 41 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@
1919
from .common import UPLOAD_CHUNK_SIZE, ClientError
2020
from .merginproject import MerginProject
2121
from .editor import filter_changes
22+
from .utils import is_qgis_file, is_versioned_file
2223

2324

2425
class UploadJob:
@@ -122,6 +123,23 @@ def push_project_async(mc, directory):
122123

123124
changes = mp.get_push_changes()
124125
changes = filter_changes(mc, project_info, changes)
126+
127+
blocking_changes, non_blocking_changes = split_changes(changes)
128+
129+
blocking_job = (
130+
_prepare_upload_job(mp, mc, project_path, local_version, blocking_changes)
131+
if any(len(v) for v in blocking_changes.values())
132+
else None
133+
)
134+
non_blocking_job = (
135+
_prepare_upload_job(mp, mc, project_path, local_version, non_blocking_changes)
136+
if any(len(v) for v in non_blocking_changes.values())
137+
else None
138+
)
139+
140+
return blocking_job, non_blocking_job
141+
142+
def _prepare_upload_job(mp, mc, project_path, local_version, changes):
125143
mp.log.debug("push changes:\n" + pprint.pformat(changes))
126144

127145
tmp_dir = tempfile.TemporaryDirectory(prefix="python-api-client-")
@@ -206,10 +224,8 @@ def push_project_async(mc, directory):
206224
for item in upload_queue_items:
207225
future = job.executor.submit(_do_upload, item, job)
208226
job.futures.append(future)
209-
210227
return job
211228

212-
213229
def push_project_wait(job):
214230
"""blocks until all upload tasks are finished"""
215231

@@ -334,3 +350,26 @@ def remove_diff_files(job) -> None:
334350
diff_file = job.mp.fpath_meta(change["diff"]["path"])
335351
if os.path.exists(diff_file):
336352
os.remove(diff_file)
353+
354+
355+
def split_changes(changes):
356+
"""Split changes into blocking and non-blocking.
357+
358+
Blocking criteria:
359+
- any updated files
360+
- any removed files
361+
- added files that are .gpkg or .qgz (.ggs)
362+
"""
363+
blocking = non_blocking = {"added": [], "updated": [], "removed": [], "renamed": []}
364+
365+
blocking["updated"] = changes["updated"]
366+
blocking["removed"] = changes["removed"]
367+
blocking["renamed"] = changes["renamed"]
368+
369+
for f in changes["added"]:
370+
if is_qgis_file(f["path"]) or is_versioned_file(f["path"]):
371+
blocking["added"].append(f)
372+
else:
373+
non_blocking["added"].append(f)
374+
375+
return blocking, non_blocking

mergin/common.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
import os
22
from enum import Enum
33

4-
CHUNK_SIZE = 100 * 1024 * 1024
4+
CHUNK_SIZE = 10 * 1024 * 1024
55

66
# there is an upper limit for chunk size on server, ideally should be requested from there once implemented
77
UPLOAD_CHUNK_SIZE = 10 * 1024 * 1024

mergin/test/test_client.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -393,7 +393,7 @@ def test_cancel_push(mc):
393393
assert next((f for f in push_changes["updated"] if f["path"] == f_updated), None)
394394

395395
# start pushing and then cancel the job
396-
job = push_project_async(mc, project_dir)
396+
job, _ = push_project_async(mc, project_dir)
397397
push_project_cancel(job)
398398

399399
# if cancelled properly, we should be now able to do the push without any problem

0 commit comments

Comments
 (0)