diff --git a/borg/archiver.py b/borg/archiver.py index 3ab156951..66ebccc16 100644 --- a/borg/archiver.py +++ b/borg/archiver.py @@ -19,7 +19,7 @@ from .helpers import Error, location_validator, format_time, format_file_size, \ format_file_mode, ExcludePattern, IncludePattern, exclude_path, adjust_patterns, to_localtime, timestamp, \ get_cache_dir, get_keys_dir, format_timedelta, prune_within, prune_split, \ Manifest, remove_surrogates, update_excludes, format_archive, check_extension_modules, Statistics, \ - is_cachedir, bigint_to_int, ChunkerParams, CompressionSpec, have_cython, \ + is_cachedir, bigint_to_int, ChunkerParams, CompressionSpec, have_cython, is_slow_msgpack, \ EXIT_SUCCESS, EXIT_WARNING, EXIT_ERROR from .logger import create_logger, setup_logging logger = create_logger() @@ -1015,6 +1015,8 @@ Type "Yes I am sure" if you understand this and want to continue.\n""") RemoteRepository.remote_path = args.remote_path RemoteRepository.umask = args.umask update_excludes(args) + if is_slow_msgpack(): + logger.warning("Using a pure-python msgpack! This will result in lower performance.") return args.func(args) diff --git a/borg/helpers.py b/borg/helpers.py index c9ffc00b7..63ef4cfae 100644 --- a/borg/helpers.py +++ b/borg/helpers.py @@ -43,6 +43,8 @@ if have_cython(): from . import crypto import msgpack +import msgpack.fallback + # return codes returned by borg command # when borg is killed by signal N, rc = 128 + N @@ -791,3 +793,7 @@ def int_to_bigint(value): if value.bit_length() > 63: return value.to_bytes((value.bit_length() + 9) // 8, 'little', signed=True) return value + + +def is_slow_msgpack(): + return msgpack.Packer is msgpack.fallback.Packer diff --git a/borg/testsuite/helpers.py b/borg/testsuite/helpers.py index a27b22719..2faa569da 100644 --- a/borg/testsuite/helpers.py +++ b/borg/testsuite/helpers.py @@ -7,9 +7,10 @@ import os import pytest import sys import msgpack +import msgpack.fallback from ..helpers import adjust_patterns, exclude_path, Location, format_file_size, format_timedelta, IncludePattern, ExcludePattern, make_path_safe, \ - prune_within, prune_split, get_cache_dir, Statistics, \ + prune_within, prune_split, get_cache_dir, Statistics, is_slow_msgpack, \ StableDict, int_to_bigint, bigint_to_int, parse_timestamp, CompressionSpec, ChunkerParams from . import BaseTestCase @@ -480,3 +481,14 @@ def test_file_size_precision(): assert format_file_size(1234, precision=1) == '1.2 kB' # rounded down assert format_file_size(1254, precision=1) == '1.3 kB' # rounded up assert format_file_size(999990000, precision=1) == '1.0 GB' # and not 999.9 MB or 1000.0 MB + + +def test_is_slow_msgpack(): + saved_packer = msgpack.Packer + try: + msgpack.Packer = msgpack.fallback.Packer + assert is_slow_msgpack() + finally: + msgpack.Packer = saved_packer + # this assumes that we have fast msgpack on test platform: + assert not is_slow_msgpack()