On Wednesday, February 5, 2014 5:03:37 PM UTC-8, Nikolaus Rath wrote:
>
> Hi Nicola,
>
> On 02/05/2014 10:52 AM, Nicola Cocchiaro wrote:
> > Hi Nikolaus,
> >
> > Are there timeouts for HTTP requests sent by S3ql? I took a look at the
> > 2.7 code (backends/common.py), and the http.client.HTTPConnection
> > constructor calls there (as well as HTTPSConnection ones) don't seem to
> > specify a timeout, and it's my understanding from the Python docs that
> > this would mean defaulting to the global default timeout. However the
> > default timeout for the socket library (which this should fall back to)
> > is None in the absence of a call to socket.setdefaulttimeout(), meaning
> > HTTP requests could block indefinitely. Is there a timeout set elsewhere
> > in code that I haven't been able to find and you can point me to?
>
> No, S3QL does not set any timeouts explicitly. It will wait until the
> server closes its side of the TCP connection, or (if the connection is
> interrupted) until the kernel's TCP stack decides the connection has
> been lost.
>
The reason I originally asked was due to seeing some outbound connections
not completing but just hanging, until using umount.s3ql would let them
return with a TimeoutError (no less than 15 minutes later in all cases
seen). I was not able to dig much deeper at the time, but to experiment
more I put together a simple patch to add a configurable socket timeout to
all S3ql tools that may make use of it. I've attached it if you'd like to
consider it.
Nicola Cocchiaro
--
You received this message because you are subscribed to the Google Groups
"s3ql" group.
To unsubscribe from this group and stop receiving emails from it, send an email
to [email protected].
For more options, visit https://groups.google.com/d/optout.
diff -ru s3ql-2.7/src/s3ql/adm-orig.py s3ql-2.7/src/s3ql/adm.py
--- s3ql-2.7/src/s3ql/adm-orig.py 2013-12-11 02:04:17.000000000 +0000
+++ s3ql-2.7/src/s3ql/adm.py 2014-03-05 23:51:06.006508081 +0000
@@ -23,6 +23,7 @@
import textwrap
import time
import atexit
+import socket
log = logging.getLogger(__name__)
@@ -61,6 +62,7 @@
parser.add_cachedir()
parser.add_version()
parser.add_fatal_warnings()
+ parser.add_socket_timeout()
options = parser.parse_args(args)
@@ -80,6 +82,10 @@
if is_mounted(options.storage_url):
raise QuietError('Can not work on mounted file system.')
+ # Set a default socket timeout if required
+ if options.socket_timeout is not None:
+ socket.setdefaulttimeout(options.socket_timeout)
+
if options.action == 'clear':
try:
backend = get_backend(options, plain=True)
diff -ru s3ql-2.7/src/s3ql/fsck-orig.py s3ql-2.7/src/s3ql/fsck.py
--- s3ql-2.7/src/s3ql/fsck-orig.py 2013-12-11 02:04:18.000000000 +0000
+++ s3ql-2.7/src/s3ql/fsck.py 2014-03-05 23:50:53.236750083 +0000
@@ -27,6 +27,7 @@
import textwrap
import time
import atexit
+import socket
log = logging.getLogger(__name__)
@@ -1056,6 +1057,7 @@
parser.add_version()
parser.add_storage_url()
parser.add_fatal_warnings()
+ parser.add_socket_timeout()
parser.add_argument("--batch", action="store_true", default=False,
help="If user input is required, exit without prompting.")
@@ -1078,6 +1080,10 @@
if is_mounted(options.storage_url):
raise QuietError('Can not check mounted file system.')
+ # Set a default socket timeout if required
+ if options.socket_timeout is not None:
+ socket.setdefaulttimeout(options.socket_timeout)
+
try:
backend = get_backend(options)
except DanglingStorageURLError as exc:
diff -ru s3ql-2.7/src/s3ql/mkfs-orig.py s3ql-2.7/src/s3ql/mkfs.py
--- s3ql-2.7/src/s3ql/mkfs-orig.py 2013-12-11 02:04:18.000000000 +0000
+++ s3ql-2.7/src/s3ql/mkfs.py 2014-03-05 23:51:24.026166592 +0000
@@ -24,6 +24,7 @@
import tempfile
import time
import atexit
+import socket
log = logging.getLogger(__name__)
@@ -40,6 +41,7 @@
parser.add_version()
parser.add_storage_url()
parser.add_fatal_warnings()
+ parser.add_socket_timeout()
parser.add_argument("-L", default='', help="Filesystem label",
dest="label", metavar='<name>',)
@@ -94,6 +96,10 @@
log.warning('Warning: maximum object sizes less than 1 MiB will seriously degrade '
'performance.', extra={ 'force_log': True })
+ # Set a default socket timeout if required
+ if options.socket_timeout is not None:
+ socket.setdefaulttimeout(options.socket_timeout)
+
try:
plain_backend = get_backend(options, plain=True)
atexit.register(plain_backend.close)
diff -ru s3ql-2.7/src/s3ql/mount-orig.py s3ql-2.7/src/s3ql/mount.py
--- s3ql-2.7/src/s3ql/mount-orig.py 2013-12-11 02:04:18.000000000 +0000
+++ s3ql-2.7/src/s3ql/mount.py 2014-03-05 19:57:57.621599740 +0000
@@ -36,6 +36,7 @@
import time
import shutil
import atexit
+import socket
log = logging.getLogger(__name__)
@@ -104,6 +105,10 @@
"available file descriptors.", options.max_cache_entries, avail_fd)
options.max_cache_entries = avail_fd
+ # Set a default socket timeout if required
+ if options.socket_timeout is not None:
+ socket.setdefaulttimeout(options.socket_timeout)
+
if options.profile:
import cProfile
import pstats
@@ -509,6 +517,7 @@
parser.add_version()
parser.add_storage_url()
parser.add_fatal_warnings()
+ parser.add_socket_timeout()
parser.add_argument("mountpoint", metavar='<mountpoint>', type=os.path.abspath,
help='Where to mount the file system')
diff -ru s3ql-2.7/src/s3ql/parse_args-orig.py s3ql-2.7/src/s3ql/parse_args.py
--- s3ql-2.7/src/s3ql/parse_args-orig.py 2013-12-11 02:04:18.000000000 +0000
+++ s3ql-2.7/src/s3ql/parse_args.py 2014-03-05 20:04:52.363740028 +0000
@@ -176,6 +176,14 @@
'it reaches 1 MiB, and at most 5 old log files will be kept. '
'Specify ``none`` to disable logging. Default: ``%(default)s``')
+ def add_socket_timeout(self, default=None):
+ self.add_argument("--socket-timeout", metavar='<socket-timeout>', default=default,
+ type=float,
+ help='Set a default socket timeout (in seconds) which will affect '
+ 'all newly created sockets and will disable the default '
+ 'blocking mode.')
+
+
def add_fatal_warnings(self):
# Make all log messages of severity warning or higher raise
# exceptions. This option is not listed in the --help output and used by