Profiles, Locks, Mergers and Acquisitions
First note that problems with locks can actually exist without profiles.
Second note that the locking mechanism used by Mozilla is flawed:
- Create a profile victim.
- Create a profile attacker.
In the attacker profile, change all the paths to match the victim profile.
You can share:
- Cache
- Bookmarks
- Mail
You can not share the following in this fashion:
- Cookies
- History
- Preferences
- Profile Lock
OK, so what would happen if you did this?
you could have two running applications corrupting bookmarks, cache and mail.
The Profile Lock only protects (D-F) because it lives in the same directory as them and their locations
aren't configurable.
So really, what should be done about this?
Well, the lock should be split.
It turns out that we're sort of doing this already with the Mozilla 1.5 proposal, your Mail profile
lock (Gm) will protect a set ACF and your Browser profile lock (Gb) will protect a set ABDEF. Does this split
prevent two profiles from tripping over any A, B or C? No, of course not, only a per directory lock
would do that.
About locks in Mozilla
Currently profiles aren't really cross platform, but suppose we actually fix them so that at least
preferences use relative file paths when possible. What happens if you use a profile on windows, BeOS,
Linux, and Mac OS X? It turns out that the name of the profile lock isn't the same. So while the windows
lock will protect you from another Mozilla-w32 process it might not protect you from a Mozilla-Mac OS X
process.
More pressing concerns in profile land.
The Linux profile lock marks a profile with an IP address and a PID. So what happens if your system
crashes, is configured with DHCP and gets a different IP address the next time it runs? Well, in today's
world you'd have to find the lock file and kill it.
Can we do better than that?
Well, perhaps we can ping the IP address listed in the lock file.
Ping
If it's down then we can make the somewhat unsafe but probably relatively reasonable assertion that the
profile is available.
Are there any restrictions to this approach?
We should probably only do it if the lock is somewhat stale (5+ minutes).
Why?
Well, why not?
suppose your computer actually did crash, it'd take it some time to boot and some
time for
the profile using application to load and some time to connect to this network storage device. Plus you
don't need to write changes to the profile immediately so letting the user use the profile and storing
data in memory for the remaining minutes wouldn't be such a big deal.
In the event that the computer doesn't respond to pings but does update the profile data the application
could write a file 'noicmp' to indicate that the ICMP test doesn't work.
So what happens today when a user runs into a profile lock?
Mozilla tosses up a dialog saying that the profile is locked and refuses to let you use it.
That's great. What's wrong with this picture?
- It tosses up a dialog
- The dialog does not offer a recourse
- The user is blocked from doing stuff which the user expects to be able to do
That doesn't sound very nice. What did n4 (4xp) do?
Netscape 4 tossed up a dialog which indicated that you could use the profile readonly if you continued.
ReadOnly
Why is this better?
Instead of 1, 2 and 3, n4 did 1 and did the opposite of 2 and 3.
The dialog told the user how to use the data and the user was allowed to use the data.
Was it perfect?
Probably not.
Is it better than Mozilla/5?
Certainly.
What are locks
In computer science a lock is supposed to be used for the shortest duration possible to maintain integrity
with a balancing factor that requires you to consider the cost of acquiring the lock.
Does the current architecture honor those concerns?
Not really. The profile data lock is acquired early and held for as long as possible. It isn't
really released until the user quits or selects to use a new profile and therefore its associated lock.
Would it be possible to limit the duration of locks so that if you left your computer for a while
and the power failed before you came back, your data would be saved and there wouldn't be a lock to
contend with?
Sleeping Gracefully
It should be possible to do this.
What would the application have to do?
It would have to detect that the user isn't using it and flush profile data to disk. Then it would need
to release the lock and be prepared to contend with another process for the lock in the event that the
user actually switches to another computer and starts to use the now available profile.
Sleeping gracefully is unfortunately very much dependent on another concept, what should happen if the
user does manage to make changes to two copies of profile data and one instance of the program notices.
Let's look at sharing your bookmarks file.
Netscape 4 and earlier allowed you to choose your bookmarks file location using manage bookmarks, file,
open.
It turns out that users actually would change their bookmarks files while their browser was open.
So what did Netscape 4 do about this?
Detecting External Changes
Netscape 4 would detect that the file was changed, probably by checking the file's date/time-stamp and
size. When it detected a change it would ask you whether you wanted to load the new bookmarks file or keep
the one you were using.
What does Mozilla/5 do if the user changes the bookmarks file while Mozilla is open?
Nothing :), the changes will be clobbered when Mozilla quits. There isn't any code to check for this case.
So things improved from Mozilla/5 to Mozilla/4... oh wait, whoops... Right...
What should have happened in the evolution from Mozilla/4 to Mozilla/5 was instead of dropping the
feature, it should have been improved.
How could you improve it?
In addition to offering to delete the
current/new file, you could offer to merge the two, or import the new bookmarks.
| Someone asked today how to reload bookmarks, i believe one would do this:
| Components.classes["@mozilla.org/browser/bookmarks-service;1"].
| getService(Components.interfaces.nsIObserver).
| observe(0, "profile-after-change", "")
Could the approach of detecting changes to Bookmarks on disk and responding to them be applied to
anything
else?
Yes :), you can merge/replace cookies, permissions (cookperm.txt), and history.
You can't easily merge changes to preferences, cache or mail.
In my experience w/ n4 mail, mailnews tended to only keep things open if it was really using them. Also
changes to mail folders tend to either be simple line changes or append operations, things which wouldn't
usually disturb other applications (except summaries/indexes).
Would it be possible to merge changes to preferences?
Yes, but it probably isn't worth it, although at least detecting changes to the preferences file would
probably be a good idea.
What about the cache directory?
Necko's cache is very sensitive, it's so sensitive that if Mozilla/5 crashes, necko will blow away the
cache directory the next time it launches because it doesn't trust that the cache will be consistent
enough to be used safely.
So is there any locking that could help the cache directory?
There are two things which might help.
- Monitoring the cache directory for changes made by another application.
-If something else changes the cache then it isn't locked well enough and something should stop
treating it as if it has a write lock.
- Implementing support for a readonly cache directory and perhaps a secondary cache directory.
-If you do decide that the cache directory is being used by someone else you have pretty much three
choices.
- Ignore that fact and proceed as if nothing's wrong, knowing full well that something bad will happen.
:)
- Stop writing to the cache, but continue using the cache as a cache of old data because it's there.
- Finding some other place to cache stuff (a temp directory or ram)
Mozilla/5 does something like A, except that it doesn't even check to make sure that no one is using the
directory. Obviously B and C are better, although they would require coding.
Are there uses for a readonly cache?
Yes.
Are there uses for a secondary cache?
Sure, whenever one wants to cache things and the primary cache is readonly.
Would you need to implement
it right away in order to use a readonly cache?
No, it could be implemented later.
Putting it all together
So if a profile started running in a readonly mode, ala n4, how could we improve the behavior?
A thread could be started to monitor the lockfile(s). If the lock becomes available, the thread would
capture the lock and then figure out what files need to be reconciled. At some point, the UI thread would
inform the user that it can now write to the profile directory, and offer the user the opportunity to
reconcile files or run readonly permanently.