From f8c2c8f879fd3866d4375d94124f82c985ef340e Mon Sep 17 00:00:00 2001 From: Markus Unterwaditzer Date: Sat, 19 Apr 2014 22:35:49 +0200 Subject: [PATCH 1/3] Use multiple connections when syncing. --- example.cfg | 6 ++++++ vdirsyncer/cli.py | 45 ++++++++++++++++++++++++++++++--------------- 2 files changed, 36 insertions(+), 15 deletions(-) diff --git a/example.cfg b/example.cfg index a5ba092..3e07ee8 100644 --- a/example.cfg +++ b/example.cfg @@ -5,6 +5,12 @@ # A folder where vdirsyncer can store some metadata about each pair. status_path = ~/.vdirsyncer/status/ +# The amount of processes to use when synchronizing. If the CPU of your server +# is the bottleneck (which is plausible for small homeservers), set this to the +# number of cores * 2. Defaults to one process for each collection. The value +# 0 will be ignored. +#processes = + # CONTACTS [pair bob_contacts] # Similar to accounts in OfflineIMAP. diff --git a/vdirsyncer/cli.py b/vdirsyncer/cli.py index f2128fa..1f1df37 100644 --- a/vdirsyncer/cli.py +++ b/vdirsyncer/cli.py @@ -190,23 +190,38 @@ def _main(env, file_cfg): config_a.update(all_storages[a_name]) config_b = dict(storage_defaults) config_b.update(all_storages[b_name]) - a = storage_instance_from_config(config_a) - b = storage_instance_from_config(config_b) - def x(a=a, b=b, pair_name=pair_name, collection=collection): - status_name = \ - '_'.join(filter(bool, (pair_name, collection))) - pair_description = \ - ' from '.join(filter(bool, (collection, pair_name))) - cli_logger.info('Syncing {}'.format(pair_description)) - status = load_status(general['status_path'], status_name) - sync(a, b, status, - pair_options.get('conflict_resolution', None)) - save_status(general['status_path'], status_name, status) - actions.append(x) - for action in actions: - action() + actions.append({ + 'config_a': config_a, + 'config_b': config_b, + 'pair_name': pair_name, + 'collection': collection, + 'pair_options': pair_options, + 'general': general + }) + + from multiprocessing import Pool + p = Pool(processes=general.get('processes', 0) or len(actions)) + p.map(_sync_collection, actions) app.register_command('sync', sync_command) app() + +def _sync_collection(x): + return sync_collection(**x) + +def sync_collection(config_a, config_b, pair_name, collection, pair_options, + general): + a = storage_instance_from_config(config_a) + b = storage_instance_from_config(config_b) + + status_name = \ + '_'.join(filter(bool, (pair_name, collection))) + pair_description = \ + ' from '.join(filter(bool, (collection, pair_name))) + cli_logger.info('Syncing {}'.format(pair_description)) + status = load_status(general['status_path'], status_name) + sync(a, b, status, + pair_options.get('conflict_resolution', None)) + save_status(general['status_path'], status_name, status) From 6c81fd6fc2f6f0fe27935a41b987794efff6c2f2 Mon Sep 17 00:00:00 2001 From: Markus Unterwaditzer Date: Sat, 19 Apr 2014 23:59:35 +0200 Subject: [PATCH 2/3] Don't use multiprocessing when having one process --- vdirsyncer/cli.py | 16 +++++++++++++--- 1 file changed, 13 insertions(+), 3 deletions(-) diff --git a/vdirsyncer/cli.py b/vdirsyncer/cli.py index 1f1df37..2af91cf 100644 --- a/vdirsyncer/cli.py +++ b/vdirsyncer/cli.py @@ -201,9 +201,19 @@ def _main(env, file_cfg): 'general': general }) - from multiprocessing import Pool - p = Pool(processes=general.get('processes', 0) or len(actions)) - p.map(_sync_collection, actions) + processes = general.get('processes', 0) or len(actions) + cli_logger.debug('Using {} processes.'.format(processes)) + + if processes == 1: + cli_logger.debug('Not using multiprocessing.') + _map = map + else: + cli_logger.debug('Using multiprocessing.') + from multiprocessing import Pool + p = Pool(processes=general.get('processes', 0) or len(actions)) + _map = p.map + + _map(_sync_collection, actions) app.register_command('sync', sync_command) app() From 15e9446bbea4cfe7ebfaef9a7368681d6b5184c3 Mon Sep 17 00:00:00 2001 From: Markus Unterwaditzer Date: Sun, 20 Apr 2014 00:01:41 +0200 Subject: [PATCH 3/3] Update cfg about special case in multiprocessing --- example.cfg | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/example.cfg b/example.cfg index 3e07ee8..0b12929 100644 --- a/example.cfg +++ b/example.cfg @@ -8,7 +8,7 @@ status_path = ~/.vdirsyncer/status/ # The amount of processes to use when synchronizing. If the CPU of your server # is the bottleneck (which is plausible for small homeservers), set this to the # number of cores * 2. Defaults to one process for each collection. The value -# 0 will be ignored. +# 0 will be ignored, the value 1 disables multiprocessing. #processes = # CONTACTS