Return-Path: X-Original-To: notmuch@notmuchmail.org Delivered-To: notmuch@notmuchmail.org Received: from localhost (localhost [127.0.0.1]) by olra.theworths.org (Postfix) with ESMTP id 5249B431FB6 for ; Wed, 23 Feb 2011 22:59:41 -0800 (PST) X-Virus-Scanned: Debian amavisd-new at olra.theworths.org X-Spam-Flag: NO X-Spam-Score: -0.699 X-Spam-Level: X-Spam-Status: No, score=-0.699 tagged_above=-999 required=5 tests=[DKIM_SIGNED=0.1, DKIM_VALID=-0.1, FREEMAIL_FROM=0.001, RCVD_IN_DNSWL_LOW=-0.7] autolearn=disabled Received: from olra.theworths.org ([127.0.0.1]) by localhost (olra.theworths.org [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id ID4jYYYSjebk for ; Wed, 23 Feb 2011 22:59:40 -0800 (PST) Received: from mail-qy0-f181.google.com (mail-qy0-f181.google.com [209.85.216.181]) (using TLSv1 with cipher RC4-SHA (128/128 bits)) (No client certificate requested) by olra.theworths.org (Postfix) with ESMTPS id 5E05A431FB5 for ; Wed, 23 Feb 2011 22:59:40 -0800 (PST) Received: by qyg14 with SMTP id 14so226947qyg.5 for ; Wed, 23 Feb 2011 22:59:37 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=gamma; h=domainkey-signature:mime-version:sender:in-reply-to:references:date :x-google-sender-auth:message-id:subject:from:to:cc:content-type :content-transfer-encoding; bh=cb6tO1y5W27a9Vns4QgkpclK3lsKQeKyhSXOX/bnPvk=; b=FTWspv6fMLWEc1clqOHBlcKSOzH9I9mcI6zb4jXxxZLjnnfn+kSRpcIBiBSyvI99Ut T3SLZ3VDSaR54rGNFkP1LFWbmxQJUEONNJt+dURWY0RQBqxy2Gk7fdYzQY51pp5/t+NY 4zBBjYWtvw6mfI5fUyOV+PC1O0f5F/8xz9N64= DomainKey-Signature: a=rsa-sha1; c=nofws; d=gmail.com; s=gamma; h=mime-version:sender:in-reply-to:references:date :x-google-sender-auth:message-id:subject:from:to:cc:content-type :content-transfer-encoding; b=OB3D+mtI8PT4+DP4wgiCdbLf1MViTZsjPQWoZT/nV71Il8Fi0+2U5nhw+uxbgugdrY TEo982DMkF/Il8A1EnriO4+todAUd6whB1nYH67segihRLsJE8be6LS0izUhzFRzq9S9 UEQhZg+f8H73CGwUYyodZyy7oAsNbjA+1lbxs= MIME-Version: 1.0 Received: by 10.229.88.67 with SMTP id z3mr325635qcl.138.1298530777715; Wed, 23 Feb 2011 22:59:37 -0800 (PST) Sender: amdragon@gmail.com Received: by 10.229.105.68 with HTTP; Wed, 23 Feb 2011 22:59:37 -0800 (PST) In-Reply-To: References: <87fwsetdin.fsf@kepler.schwinge.homeip.net> <8762taxk9y.fsf@algae.riseup.net> <87vd1a84qj.fsf@servo.finestructure.net> Date: Thu, 24 Feb 2011 01:59:37 -0500 X-Google-Sender-Auth: qYiCc3kecjQ3HtWhs1hhA2N7SHw Message-ID: Subject: Re: notmuch's idea of concurrency / failing an invocation From: Austin Clements To: notmuch@notmuchmail.org Content-Type: text/plain; charset=ISO-8859-1 Content-Transfer-Encoding: quoted-printable Cc: Thomas Schwinge X-BeenThere: notmuch@notmuchmail.org X-Mailman-Version: 2.1.13 Precedence: list List-Id: "Use and development of the notmuch mail system." List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Thu, 24 Feb 2011 06:59:41 -0000 Now that I've split notmuch new up in to lots of small transactions, I think the database locking issue is quite approachable. Here's a proposed locking protocol where a notmuch operation that wants to modify the database blocks if there's another operation in progress (instead of immediately failing like now), but indicates to the in-progress operation that, when convenient, it should temporarily abdicate the database. Add a file to the .notmuch directory, say "lock", which we'll use for fcntl locks (fcntl locks have nice properties, like automatic cleanup on process exit and NFS compatibility). To open the database for write, 1. Acquire an exclusive lock on byte 0 of the lock file (in blocking mode) 2. Acquire an exclusive lock on byte 1 of the lock file 3. Release the lock on byte 0 4. Open the Xapian database When it's convenient to abdicate the lock, test if there are pending operations by testing for a lock on byte 0 of the lock file using F_GETLK. If there's no lock on byte 0, just continue without releasing the database. Otherwise, 1. Close the Xapian database 2. Release the lock on byte 1 3. Re-lock and re-open the database. In effect, this acts like one lock, since byte 1 is only ever acquired while byte 0 is held, but splitting it across two locks like this lets us "peek" at the waiter queue and see if someone is waiting. Some possible extensions: We may want a timeout for how long to wait for the lock (in case the lock holder gets wedged). We could work around DatabaseModified exceptions by having readers do essentially the same thing as writers, but take the locks in shared mode. Readers wouldn't proceed in parallel with writers, but long-running writers would relinquish the lock, so this isn't so bad. Finally, concurrent notmuch new's should probably be serialized (instead of repeatedly abdicating to each other), so it may make sense to have an additional "notmuch new lock". On Thu, Jan 27, 2011 at 5:20 PM, Austin Clements wrote: > I'm looking into breaking notmuch new up into small transactions. =A0It > wouldn't be much a leap from there to simply close and reopen the databas= e > between transactions if another task wants to use it, which would release > the lock and let the queued notmuch task have the database for a bit. =A0= It > seems silly to have a daemon when all of notmuch's state is already on di= sk > and queue on a lock is as good as a queue in a daemon, but without the > accompanying architectural=A0shenanigans.