From: Andrew S. <som...@gm...> - 2005-06-29 06:33:22
|
I was doing some work this evening with j and my computer got in a bad way when it had to be rebooted. When j started up again, it prompted me to choose to restore an autosave file. Even though I was relatively confident I had manually saved the file before the badness, I chose to restore, thinking 'what harm could it do' (famous last words ;). For whatever reason, the backup was rather old and missing a sizable amount of code. I was under the (mistaken) impression I was going to get MS Word type recovery where it opens the restored file into a buffer, but does not save it to disk. In contrast, at least in this case, j deletes the authoritative file and replaces it with the autosave. In most cases this shouldn't be much of a delta (and the delta should be in the user's favor), but this can clearly turn out badly as it did in this case. I think the code knows this, because it has the comment "BUG! Should back up old file first!" in the given code path. In any event, the minimal patch below somewhat dubiously changes this code path to open the buffer pretending that the autosave file is a cache file, additionally marking the file modified. A change is made to the session restoration code to deal with the likely case where the restored file was part of the session. This accomplishes what I was originally hoping for, and I don't see how it could really be any worse that irrevocably nuking a file. There's also the nice side effect that j cleans up the autosave file in question once the editor safely exits. (If j crashes before deleting the autosave-become-cache, it gets left there and becomes the user's problem to clean up...) In any event, continued props for writing (and actively maintaining) such a nice editor that I keep coming back to. Thanks, Andrew Sutherland Index: Autosave.java =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D RCS file: /cvsroot/armedbear-j/j/j/src/org/armedbear/j/Autosave.java,v retrieving revision 1.2 diff -u -r1.2 Autosave.java --- Autosave.java 11 Oct 2002 14:06:18 -0000 1.2 +++ Autosave.java 29 Jun 2005 06:15:34 -0000 @@ -178,11 +178,16 @@ } } } else { - // BUG! Should back up old file first! - file.delete(); - // BUG! Error handling! What if rename and copy both fail? - if (autosaveFile.renameTo(file) || Utilities.copyFile(autosaveFile, file)) { - autosaveFile.delete(); + // Trick it into loading the contents from the autosave fi= le + // by pretending to be a cache file. + Buffer buf =3D Buffer.createBuffer(file, autosaveFile, nul= l); + if (buf !=3D null) { + // Mark as changed! + buf.incrementModCount(); + + // Now that the buffer owns the autosave, we can remov= e the + // autosave from the catalog. (Even if we didn't, th= e + // catalog file would still get deleted...) catalog.remove(netPath); } } Index: Session.java =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D RCS file: /cvsroot/armedbear-j/j/j/src/org/armedbear/j/Session.java,v retrieving revision 1.11 diff -u -r1.11 Session.java --- Session.java 29 Jun 2003 00:19:34 -0000 1.11 +++ Session.java 29 Jun 2005 06:15:34 -0000 @@ -217,8 +217,14 @@ if (entry !=3D null) { File file =3D File.getInstance(entry.getPath()); if (file !=3D null && file.isLocal()) { - Buffer buf =3D null; - if (file.isDirectory()) + // See if a buffer already exists. (The buffer would = have + // been created by autosave recovering a local file.) + Buffer buf =3D Editor.getBufferList().findBuffer(file)= ; + + if (buf !=3D null) { + // do nothing, we already have a buffer + } + else if (file.isDirectory()) buf =3D new Directory(file); else if (file.isFile() && file.canRead()) { if (entry.getModeId() =3D=3D WEB_MODE) |
From: Peter G. <pe...@ar...> - 2005-07-04 22:26:09
|
On Wed, 29 Jun 2005 at 02:33:18 -0400, Andrew Sutherland wrote: > I was doing some work this evening with j and my computer got in a bad > way when it had to be rebooted. When j started up again, it prompted > me to choose to restore an autosave file. Even though I was > relatively confident I had manually saved the file before the badness, > I chose to restore, thinking 'what harm could it do' (famous last > words ;). For whatever reason, the backup was rather old and missing > a sizable amount of code. That in itself is a bit odd, since j normally autosaves unsaved buffers whenever the user is idle (from a j point of view) for 2 seconds, and since the autosave happens in a separate thread, it should be done even if j's main thread is hung. But of course if your computer is going south all sorts of odd things can happen. > I was under the (mistaken) impression I was going to get MS Word type > recovery where it opens the restored file into a buffer, but does not > save it to disk. In contrast, at least in this case, j deletes the > authoritative file and replaces it with the autosave. In most cases > this shouldn't be much of a delta (and the delta should be in the > user's favor), but this can clearly turn out badly as it did in this > case. I think the code knows this, because it has the comment "BUG! > Should back up old file first!" in the given code path. Yeah. That code dates from 2002, and it was never really a 100% solution, but it worked well enough that I've never gone back to clean things up. > In any event, the minimal patch below somewhat dubiously changes this > code path to open the buffer pretending that the autosave file is a > cache file, additionally marking the file modified. A change is made > to the session restoration code to deal with the likely case where the > restored file was part of the session. This accomplishes what I was > originally hoping for, and I don't see how it could really be any > worse that irrevocably nuking a file. There's also the nice side > effect that j cleans up the autosave file in question once the editor > safely exits. (If j crashes before deleting the > autosave-become-cache, it gets left there and becomes the user's > problem to clean up...) That's a very clever solution. I would not have thought it possible to accomplish all that with such a small patch. I've committed your changes more or less verbatim. > In any event, continued props for writing (and actively maintaining) > such a nice editor that I keep coming back to. Thanks for a great patch! -Peter |