A munkaterület-mentési feldolgozás akkor aktiválódik, amikor a felhasználó leállítja a munkaterületet és más időpontokban rendszeres időközönként, amikor a platform leállítja. A bedolgozók résztvehetnek a munkaterület-mentési folyamatban, így a kritikus bedolgozóadatok mentésre kerülnek a lemezre, amikor a munkaterület állandó adatainak maradéka mentésre kerül.
A munkaterület-mentési folyamat a bedolgozó tevékenységei közötti módosítások nyomkövetéséhez is használható.
A munkaterület-mentésben részvétel érdekében hozzá kell adni egy mentésrésztvevőt a munkaterülethez. Ez jellemzően a bedolgozó indítási metódusa során történik. Ez szintén az, ahol bedolgozó utolsó leállításakor elmentett állapotok kiolvashatók.
Tekintsen meg egy egyszerű bedolgozót, amely bemutatja a mentési folyamatot.
package com.example.saveparticipant; import org.eclipse.core.runtime.*; import org.eclipse.core.resources.*; import java.io.File; import java.util.*; public class MyPlugin extends Plugin { private static MyPlugin plugin; public MyPlugin(IPluginDescriptor descriptor) { super(descriptor); plugin = this; } public static MyPlugin getDefault() { return plugin; } protected void readStateFrom(File target) { } public void startup() throws CoreException { super.startup(); ISaveParticipant saveParticipant = new MyWorkspaceSaveParticipant(); ISavedState lastState = ResourcesPlugin.getWorkspace().addSaveParticipant(this, saveParticipant); if (lastState == null) return; IPath location = lastState.lookup(new Path("save")); if (location == null) return; // a bedolgozópéldánynak a fontos állapotot a fájlból kell kiolvasni. File f = getStateLocation().append(location).toFile(); readStateFrom(f); } protected void writeImportantState(File target) { } }
ISaveParticipant megadja a protokollt a munkaterület-mentési résztvevőhöz. A felület megvalósítói jellemzőt biztosíthatnak a mentési folyamat különböző állapotaihoz. Tekintse meg ezeket a részeket, és hogy a WorkspaceSaveParticipant hogyan valósítja meg ezeket a lépéseket.
public void prepareToSave(ISaveContext context) throws CoreException { }
public void saving(ISaveContext context) throws CoreException { switch (context.getKind()) { case ISaveContext.FULL_SAVE: MyPlugin myPluginInstance = MyPlugin.getDefault(); // bedolgozóállapot mentése int saveNumber = context.getSaveNumber(); String saveFileName = "save-" + Integer.toString(saveNumber); File f = myPluginInstance.getStateLocation().append(saveFileName).toFile(); // ha az írás meghiúsul, akkor kivétel történik, és nem frissítjük az elérési utat myPluginInstance.writeImportantState(f); context.map(new Path("save"), new Path(saveFileName)); context.needSaveNumber(); break; case ISaveContext.PROJECT_SAVE: // a mentés művelethez tartozó projekt lekérésre IProject project = context.getProject(); // mentse el az információkat szükség eset break; case ISaveContext.SNAPSHOT: // Ennek a műveletnek igazán gyorsnak kell lennie // mivel a pillanatképeket a munkaterület // gyakran lekérheti. break; } }
Az ISaveContext a mentési művelettel kapcsolatos információkat írja le. Háromféle mentési művelet van: FULL_SAVE, SNAPSHOT és PROJECT_SAVE. A mentési résztvevőknek körültekintően kell végrehajtaniuk a kapott mentési események típusának megfelelő feldolgozást. A pillanatkép események például meglehetősen gyakran bekövetkezhetnek, és lehetővé teszik, hogy a bedolgozók elmentsék a kritikus állapotot. Az állapot mentése hosszú ideig tart, amely újra feldolgozható az összeomlás esetén, és ez lelassítja a platformot.
A mentési szám adatmentési fájlokat hoz létre, amelyek a sorszámokkal kerülnek elnevezésre (save-1, save-2, stb.) Minden mentési fájl egy logikai névre van leképezve (mentés), amely a mentési számtól független. A bedolgozóadatok beíródnak a megfelelő fájlba, és később az utolsó mentési művelet mentési számának ismerete nélkül lekérhetők. Ne feledje el, hogy ezt a technikát a saját bedolgozó indítási kódjában láttuk:
IPath location = lastState.lookup(new Path("save"));Miután elmentettük az adatokat és leképeztük a fájlnevet, meghívjuk a needSaveNumber függvényt annak jelzéséhez, hogy aktívan résztvettünk a munkaterület-mentésben, és hogy hozzá kívánunk rendelni egy számot a mentési tevékenységhez. A mentési számok segítségével adatfájlok hozhatók létre a fent látható módon.
public void doneSaving(ISaveContext context) { MyPlugin myPluginInstance = MyPlugin.getDefault(); // törli a régi mentett állapotot, mivel ez többet nem szükséges int previousSaveNumber = context.getPreviousSaveNumber(); String oldFileName = "save-" + Integer.toString(previousSaveNumber); File f = myPluginInstance.getStateLocation().append(oldFileName).toFile(); f.delete(); }
Itt kitisztítjuk a mentési információkat a korábbi mentési műveletből. A getPreviousSaveNumber segítségével lekérhető a korábbi mentési művelethez rendelt mentési szám (nem az éppen befejezett). Ezen szám segítségével állítjuk összes a törölni kívánt fájl nevét. Ne feledje el, hogy nem használjuk a mentési állapot logikai fájlleképezést, mivel már elmentettük az aktuális mentési fájlszámot.
public void rollback(ISaveContext context) { MyPlugin myPluginInstance = MyPlugin.getDefault(); // mivel a mentés művelet meghiúsult, törölje az éppen írt mentett állapotot int saveNumber = context.getSaveNumber(); String saveFileName = "save-" + Integer.toString(saveNumber); File f = myPluginInstance.getStateLocation().append(saveFileName).toFile(); f.delete(); }
Itt töröljük az éppen mentett állapotot. Ne feledje el, hogy az aktuális mentési számot használjuk az éppen mentett fájl nevének összeállításához. Nem kell aggódunk amiatt, hogy a fájlnevet leképeztük az ISaveContext elemre. A platform a mentési művelet meghiúsulásakor törli ezt a kontextust.
Ha a bedolgozó kivételt okoz a mentési életciklus során, akkor eltávolításra kerül az aktuális mentési műveletből és nem kerülnek lekérésre a fennmaradó életciklus-metódusok. Ha a mentés metódus során például hiba történik, akkor egy visszagörgetés vagy doneSaving üzenet érkezik.
Ha mentés résztvevőt ad a munkaterülethez, akkor ez visszaad egy ISavedState objektumot, amely leírja, hogy mely bedolgozó kerül mentésre az utolsó mentési művelet során (vagy üres, ha a bedolgozó korábban nem mentett el egy állapotot sem). Ez az objektum elérheti a korábbi mentésfájl információit (a mentési számmal és a fájltérképpel) vagy feldolgozhatja a bedolgozó aktiválásai között történt módosításokat.
Ha a fájltérkép lokálisan elnevezett fájlokat mentenek el a mentési számnak megfelelően, akkor ugyanez a térkép használható az adatok utolsó ismert mentési állapotból lekéréséhez.
ISaveParticipant saveParticipant = new MyWorkspaceSaveParticipant(); ISavedState lastState = ResourcesPlugin.getWorkspace().addSaveParticipant(myPluginInstance, saveParticipant); if (lastState != null) { String saveFileName = lastState.lookup(new Path("save")).toString(); File f = myPluginInstance.getStateLocation().append(saveFileName).toFile(); // a bedolgozópéldánynak a fontos állapotot a fájlból kell kiolvasnia. myPluginInstance.readStateFrom(f); }
Ne feledje el, hogy tetszőleges számú erőforrás-módosítási esemény történhet a munkaterületen a bedolgozó aktiválása előtt. Ha tudni szeretné, hogy milyen módosítások történtek a bedolgozó utolsó leállítása óta, akkor ehhez használhatja a mentési mechanizmust abban az esetben is, ha más adatot nem kell menteni.
A mentés-résztvevőnek kérnie kell, hogy a platform helyette tartson fenn egy erőforrás-változásfájlt. Ez a mentési művelet részeként kerül végrehajtásra.
public void saving(ISaveContext context) throws CoreException { // nincs olyan állapot, amelyet a bedolgozónak el kell mentenie, // de egy erőforrás-változások fájl használatát igényli a következő aktiváláskor. context.needDelta(); }
A bedolgozó indítása során a korábban elmentett állapot elérhető, és módosítási események jönnek létre az utolsó mentés óta történt módosításokhoz.
ISaveParticipant saveParticipant = new MyWorkspaceSaveParticipant(); ISavedState lastState = ResourcesPlugin.getWorkspace().addSaveParticipant(myPluginInstance, saveParticipant); if (lastState != null) { lastState.processResourceChangeEvents(new MyResourceChangeReporter()); }
A biztosított osztálynak az Erőforrás-módosítások nyomkövetése részben leírt módon meg kell valósítani az IResourceChangeListener elemet. Az utolsó mentés óta történt módosítások a POST_AUTO_BUILD erőforrás-módosítási esemény részeként kerülnek jelentésre.
Megjegyzés: A jelzőmódosítások nem kerülnek jelentésre az ISavedState elemben tárolt módosításeseményekben. Fel kell tételezni, hogy a jelzők egy része az összes módosításra került az utolsó mentett állapot óta.