Munkaterület-mentés részvétel

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ó.

Mentési résztvevő megvalósítása

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. 

Korábban mentett állapot használata

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.

A mentési fájlok elérése

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);
   }

Erőforrás-változások fájl feldolgozása az aktiválások között

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.