Erőforrás-módosítások kötegelése

Ha módosítania kell a munkaterület erőforrásait, akkor ne feledje el, hogy más bedolgozók is használhatják ugyanazokat az erőforrásokat. Az erőforrások API egy robusztus mechanizmust biztosít ahhoz, hogy a bedolgozók értesítést kapjanak a munkaterület módosításairól, és annak biztosítása érdekében, hogy ezek a bedolgozók ne módosítsák egyszerre ugyanazt az erőforrást. Ahol lehetséges, a bedolgozók munkaterület-módosításait munkaegységekbe kell kötegelni a munkaterület futtatható fájlon belül. Ezek a futtatható fájlok csökkentik a módosítások által előállított módosításértesítéseket. Segítségükkel az is megadható, hogy a munkaterület mely részét kell módosítani, így kizárható, hogy a többi bedolgozó a munkaterület ugyanazon részét módosítsa.

Az IWorkspaceRunnable protokollja eléggé egyszerű. A munkaterület futtatható fájl úgy néz ki, mint egy platformfeladat hosszútávú művelete. A tényleges munka a futtatás metódusban zajlik, és előrehaladásról az IProgressMonitor jelentést kap. A munkaterületet módosító kód a futtatás metóduson belül kerül végrehajtásra.

IWorkspaceRunnable myRunnable = 
	new IWorkspaceRunnable() {
		public void run(IProgressMonitor monitor) throws CoreException {
			//a tényleges munka itt történik
			...
		}
}

Ha itt az ideje a kód futtatásának, akkor a bedolgozók utasítják a munkaterületet, hogy futtassa a kódot. Így a munkaterület létre tudja hozni a szükséges módosítási eseményeket és biztosítja, hogy ne módosítsa egyszerre két bedolgozó ugyanazt az erőforrást. (Ha a bedolgozó nem használja a háttérfeladatokat és a konkurencia-keretrendszert a munkaterület módosításához, akkor esetleg más bedolgozó teszi ezt.)

Szabályok és zárolás ütemezése

IWorkspace protokoll futtat egy munkaterület futtatható fájlt. A preferált eljárás a futtatás metódus hossz] formátumának használata, amely egy ütemező szabályt biztosít és megadja, hogy az erőforrásmódosítási események hogyan kerülnek továbbításra üzenetszórással.

Ha megad egy ütemező szabályt a munkaterület futtatható fájljának futtatásakor, akkor a munkaterület meghatározhatja, hogy az erőforrásmódosítás összeütközik-e másik szálban végrehajtott munkaterület-módosításokkal. (Az ütemezési szabályok és az ISchedulingRule protokoll áttekintését az Ütemezési szabályok rész tartalmazza.) Szerencsére az IResource protokoll tartalmazza az ISchedulingRule protokollját, amely azt jelenti, hogy az erőforrás gyakran használható ütemezési szabályként önmagához.

Összezavarodott? A kód segíthet ennek tisztázásában. Tételezzük fel, hogy a bedolgozó készen áll egy erőforrás-halmaz módosítására egy adott projektben. A módosítások elvégzéséhez használhatja magát a projektet ütemezési szabályként. Az alábbi részlet futtatja a korábban létrehozott munkaterület futtatható fájlt:

IWorkspace workspace = ResourcesPlugin.getWorkspace();
workspace.run(myRunnable, myProject, IWorkspace.AVOID_UPDATE, null);

A futtatható fájl átadódik a munkaterületnek, amelyet a kód által módosított projekt követ. Ez utasítja a munkaterületet, hogy a futtatható fájl összes módosítása a myProject elemre korlátozott. A többi szál myProject módosítására irányuló kérése blokkolásra kerül a futtatható fájl befejeződéséig. Hasonlóan ez a hívás blokkolásra kerül, ha más szál már módosítja a myProjectet. Annak megadásával, hogy az erőforrásfa mely részét módosítja a futtatható fájl, lehetővé teszi más szálak számára a munkaterület más részeinek módosítását. Meg kell győződni arról, hogy az erőforrásszabály megfelel a futtatható fájlon belül végzett feladatnak. Ha az erőforrást az ütemezési szabályon kívül próbálja elérni, akkor ez egy kivételt aktivál.

A futtatás metódus harmadik paramétere megadja, hogy a periodikus erőforrásmódosítási eseményeket üzenetszórással kell-e elküldeni a hívás során. Az IWorkspace.AVOID_UPDATE segítségével utasítja a platformot, hogy elnyomja az erőforrásmódosítási eseményeket, miközben a futtatható fájl fut, és hogy üzenetszórással küldje el az eseményt a módosítás végén. A hívás során a futtatható fájlban létrehozott más futtatható fájlok is a szülő kötegelt művelet részének lesznek tekintve. Ezen futtatható fájlokban végzett erőforrás-módosítások megjelennek a szülő erőforrásmódosítási értesítésében.

Erőforrásszabály-gyár

A fenti példában feltételeztük, hogy a futtatható fájlon kívüli kód csak módosított erőforrások egy adott projektben. Ez nagyon leegyszerűsíti az ütemezési szabály megadását a futtatható fájlhoz. Gyakorlatban okkal bonyolultabb lehet annak feldolgozása, hogy a munkaterület mely részeire van hatással az adott módosítás. Az erőforrás egyik projektből másikba mozgatása például mindkét projektre hatással van. IResourceRuleFactory segítségvet nyújt a megfelelő erőforrás-szabály feldolgozásában adott típusú erőforrásmódosításokhoz. Egy erőforrásszabály-gyárat lekérhet magáról a munkaterületről.

IWorkspace workspace = ResourcesPlugin.getWorkspace();
IResourceRuleFactory ruleFactory = workspace.getRuleFactory();

A gyár számos művelethez megfelelő szabályokat tud biztosítani. Ha a futtatható fájl egy erőforrást egyik helyről a másikra mozgat, akkor le tudja kérni a műveletnek megfelelő szabályt:

ISchedulingRule movingRule = ruleFactory.moveResource(sourceResource, destinationResource);
workspace.run(myRunnable, movingRule, IWorkspace.AVOID_UPDATE, null);

A rendelkezésre álló szabályok listáját az IResourceRuleFactory javadoc eleme tartalmaz. Az erőforrások bedolgozó ezen szabályokat használja a legtöbb erőforrás-művelet megvalósításához. Ezen szabálymetódusokra hivatkozó kód böngészése segít annak bemutatásában, hogy a gyakorlatban hogyan használhatók.

A MultiRule segítségével több szabály kombinálható.

ISchedulingRule movingRule = ruleFactory.moveResource(sourceResource, destinationResource);
ISchedulingRule modifyRule = ruleFactory.modifyResource(destinationResource);
workspace.run(myRunnable, MultiRule.combine(movingRule, modifyRule), IWorkspace.AVOID_UPDATE, null);

Szabályok figyelmen kívül hagyása

Az IWorkspace elemben a futtatás metódus rövid formája is rendelkezésre áll. Ezt a visszamenőleges kompatibilitás érdekében megtartották. A rövid forma nem tartalmaz szabály- vagy frissítésjelzőt.

workspace.run(myRunnable, null);

ez nagyjából megegyezik az alábbi hívásával:

workspace.run(myRunnable, workspace.getRoot(), IWorkspace.AVOID_UPDATE, null);

Ha a munkaterület-gyökeret adja meg ütemezési szabályként, akkor a teljes munkaterület zárolásra kerül addig, amíg a futtatható fájl be nem fejeződik. Ez munkaterület-frissítés konzervatívabb módja, de nem túl kedvező más konkurencia alapú bedolgozókhoz.