Merge lp:~cmiller/desktopcouch/find-port-runtimeerror into lp:desktopcouch

Proposed by Chad Miller
Status: Merged
Approved by: Tim Cole
Approved revision: no longer in the revision history of the source branch.
Merged at revision: not available
Proposed branch: lp:~cmiller/desktopcouch/find-port-runtimeerror
Merge into: lp:desktopcouch
Diff against target: 83 lines (+21/-21)
2 files modified
desktopcouch/__init__.py (+11/-10)
desktopcouch/start_local_couchdb.py (+10/-11)
To merge this branch: bzr merge lp:~cmiller/desktopcouch/find-port-runtimeerror
Reviewer Review Type Date Requested Status
Stuart Langridge (community) Approve
Eric Casteleijn (community) Approve
Review via email: mp+15109@code.launchpad.net

Commit message

There is a period between when couchdb has written its PID file and when it is really listening on a socket for connections. Our code assumes that writing its PID file is a signal that it's ready to work, but it is not. Now, we loop on looking for the socket, instead of interpreting missing as an error.

To post a comment you must log in.
105. By Manuel de la Peña

Ensures that the method that test for the presence of the record does not just check if the field is present but ensures the value is correct.

Revision history for this message
Eric Casteleijn (thisfred) wrote :

Looks good, tests pass.

review: Approve
Revision history for this message
Stuart Langridge (sil) wrote :

Much nicer than before. Good catch.

review: Approve
106. By Chad Miller

There is a period between when couchdb has written its PID file and when it is really listening on a socket for connections. Our code assumes that writing its PID file is a signal that it's ready to work, but it is not. Now, we loop on looking for the socket, instead of interpreting missing as an error.

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
=== modified file 'desktopcouch/__init__.py'
--- desktopcouch/__init__.py 2009-11-18 18:43:41 +0000
+++ desktopcouch/__init__.py 2009-11-21 00:00:31 +0000
@@ -57,11 +57,16 @@
5757
58 return pid58 return pid
5959
60def find_port__linux(pid=None):60def find_port__linux(pid=None, ctx=local_files.DEFAULT_CONTEXT):
61 if pid is None:61 """This returns a valid port or raises a RuntimeError exception. It never
62 pid = find_pid()62 returns anything else."""
6363 if pid is None:
64 proc_dir = "/proc/%s" % (pid,)64 pid = find_pid(start_if_not_running=True, ctx=ctx)
65
66 if pid is None:
67 raise RuntimeError("Have no PID to use to look up port.")
68
69 proc_dir = "/proc/%d" % (pid,)
6570
66 # enumerate the process' file descriptors71 # enumerate the process' file descriptors
67 fd_dir = os.path.join(proc_dir, 'fd')72 fd_dir = os.path.join(proc_dir, 'fd')
@@ -104,12 +109,8 @@
104 if match is not None:109 if match is not None:
105 port = str(int(match.group(1), 16))110 port = str(int(match.group(1), 16))
106 break111 break
112
107 if port is None:113 if port is None:
108 log.error("Unable to find listening port")
109 log.error("Looked at the following processes for inode %s:" % inode_subexp)
110 fp = open(os.path.join(proc_dir, 'net', 'tcp'))
111 log.error(fp.read())
112 fp.close()
113 raise RuntimeError("Unable to find listening port")114 raise RuntimeError("Unable to find listening port")
114115
115 return port116 return port
116117
=== modified file 'desktopcouch/start_local_couchdb.py'
--- desktopcouch/start_local_couchdb.py 2009-11-20 20:35:16 +0000
+++ desktopcouch/start_local_couchdb.py 2009-11-21 00:00:31 +0000
@@ -63,8 +63,6 @@
63def create_ini_file(port="0", ctx=local_files.DEFAULT_CONTEXT):63def create_ini_file(port="0", ctx=local_files.DEFAULT_CONTEXT):
64 """Write CouchDB ini file if not already present"""64 """Write CouchDB ini file if not already present"""
6565
66 print "ini file is at", ctx.file_ini
67
68 if os.path.exists(ctx.file_ini):66 if os.path.exists(ctx.file_ini):
69 # load the username and password from the keyring67 # load the username and password from the keyring
70 try:68 try:
@@ -220,20 +218,21 @@
220 exit(1)218 exit(1)
221219
222 # give the process a chance to start220 # give the process a chance to start
223 for timeout in (0.1, 0.1, 0.2, 0.5, 1, 3, 5):221 for timeout in (0.4, 0.1, 0.1, 0.2, 0.5, 1, 3, 5):
224 pid = read_pidfile(ctx=ctx)222 pid = read_pidfile(ctx=ctx)
225 if pid is not None and process_is_couchdb(pid):223 if pid is not None and process_is_couchdb(pid):
226 break224 break
227 print "...waiting for couchdb to start..."
228 time.sleep(timeout)225 time.sleep(timeout)
229226
230 # loop for a number of times until the port has been found, this227 # Loop for a number of times until the port has been found, this
231 # has to be done to prevent a race condition when trying to retrieve228 # has to be done because there's a slice of time between PID being written
232 # the port number is slow hardware (ie netbooks)229 # and the listening port being active.
233 for timeout in (0.1, 0.1, 0.2, 0.5, 1, 3, 5):230 for timeout in (0.1, 0.1, 0.2, 0.5, 1, 3, 5, 8):
234 port = desktopcouch.find_port(pid=pid)231 try:
235 if port is not None: break232 port = desktopcouch.find_port(pid=pid, ctx=ctx) # only returns valid port
236 print "...waiting for couchdb to start..."233 break
234 except RuntimeError, e:
235 pass
237 time.sleep(timeout)236 time.sleep(timeout)
238237
239 ctx.ensure_files_not_readable()238 ctx.ensure_files_not_readable()

Subscribers

People subscribed via source and target branches