怎么简单的锁定文件夹_简单性与鲁棒性–在锁定文件处理中展示
怎么簡單的鎖定文件夾
今天,我們將討論使事情保持簡單,愚蠢(KISS)和魯棒性的設(shè)計價值之間,設(shè)計不足和過度設(shè)計之間的沖突。
我們正在編寫一個批處理Java應用程序,需要確保在服務器上一次最多運行一個實例。 團隊成員有一個很好的想法,那就是使用鎖定文件,這確實有效并且對我們有很大幫助。 但是,最初的實現(xiàn)不是很健壯,由于對該死的應用程序拒絕運行和查找鎖定文件進行故障排除,這使我們花費了寶貴的時間和昂貴的上下文切換。
正如Comoyo的?yvindBakksj?最近解釋的那樣,軟件工程師與純粹的編碼器的不同之處在于,不僅要思考和關(guān)心通過代碼的快樂路徑,而且還要考慮不快樂的情況。 優(yōu)秀的工程師會考慮可能出現(xiàn)的問題,并嘗試適當?shù)靥幚硭鼈?#xff0c;以便依賴于它們和其用戶的代碼可以更輕松地處理有問題的情況。 健壯性包括及早發(fā)現(xiàn)錯誤,以良好的方式處理錯誤以及提供有用和有用的錯誤消息。 另一方面,簡單性[TBD:Hickey]是系統(tǒng)的關(guān)鍵特征。 花太多時間來制作防彈代碼總是很容易,而不是將精力集中在對業(yè)務更有價值的地方。
過于簡單的實現(xiàn)
最初的實現(xiàn)非常簡單:
public class SimpleSingletonBatchJob {private static boolean getLock() {File file = new File(LOCK_DIRECTORY+File.separatorChar+Configuration.getGroupPrefix());try {return file.createNewFile();} catch (IOException e) {return false;}}private static void releaseLock() {File file = new File(LOCK_DIRECTORY+File.separatorChar+Configuration.getGroupPrefix());file.delete();}public static void exit(int nr) {releaseLock();System.exit(nr);}public static void main(String[] args) throws IOException {...if (! getLock()) { // #1 try to create lockSystem.out.println("Already running");return;}... // do the job (may throw exceptions)releaseLock(); // #2 release lock when done} }主要問題是,如果該應用程序失敗或被終止,它將留下鎖定文件,而下次它將拒絕并以無用的錯誤消息開頭。 您將需要了解/閱讀代碼以了解如何解決問題。
有人認為,這樣的失敗和故意的失敗只會很少發(fā)生,以致于使代碼更健壯的努力是沒有道理的。 但是,我們需要投入很少的精力來使代碼更加友好和健壯,f.ex。 通過在錯誤消息中包括鎖定文件路徑并解釋為什么可能存在鎖定文件路徑以及如何解決該問題(例如“如果應用未運行,則鎖定是失敗運行的殘余,可能會被刪除”)。 確保在失敗時刪除文件是一些瑣碎的代碼行,可以節(jié)省一些混亂和時間。 另外,值得一提的是使其更強大,從而不需要太多的人工干預–對您的操作人員很友好。 (我希望是你。)
更強大的實施
這是改進的版本,具有有用的錯誤消息,并在失敗時刪除鎖:
public class RobustSingletonBatchJob {// Note: We could use File.deleteOnExit() but the docs says it is not 100% reliable and recommends to// use java.nio.channels.FileLock; however this code works well enough for usstatic synchronized boolean getLock() {File file = new File(LOCK_DIRECTORY, StaticConfiguration.getGroupPrefix());try {// Will try to create path to lockfile if it does not exist.file.getParentFile().mkdirs(); // #1 Create the lock dir if it doesn't existif (file.createNewFile()) {return true;} else {log.info("Lock file " + file.getAbsolutePath() + " already exists."); // #2 Helpful error msg w/ pathreturn false;}} catch (IOException e) {throw new RuntimeException("Failed to create lock file " + file.getAbsolutePath()+ " due to " + e + ". Fix the problem and retry.", e); // #3 Helpful error message with context (file path)}}private synchronized static void releaseLock() {File file = new File(LOCK_DIRECTORY, StaticConfiguration.getGroupPrefix());file.delete();}public static void main(String[] args) throws Exception {boolean releaseLockUponCompletion = true;try {...if (! getLock() {releaseLockUponCompletion = false;log.error("Lock file is present, exiting."); // Lock path already loggedthrow new RuntimeException("Lock file is present"); // throwing is nicer than System.exit/return}... // do the job (may throw exceptions)} finally {if (releaseLockUponCompletion) {releaseLock(); // #4 Always release the lock, even upon exceptions}} }改進之處:
代碼仍然不是完美的-如果您終止了該應用程序,則鎖定文件仍將留下。 有多種方法可以解決該問題(例如,將應用程序的pid包含在文件中,在啟動時不僅檢查其是否存在,而且還應檢查pid確實存在/是否為該應用程序),但是在處理時間方面和增加成本方面復雜性的確高于收益。
結(jié)論
KISS和魯棒性都是重要目標,并且經(jīng)常會發(fā)生沖突。 使您的代碼變得比所需的更健壯會使其變得過于復雜,并浪費時間,并且機會成本(丟失)。 由于故障排除,使代碼過于簡單會花費您或它的用戶大量時間。 要實現(xiàn)正確的平衡,需要經(jīng)驗并不斷地尋求平衡。 如果您的團隊無法達成共識,最好從一個簡單的代碼開始,并根據(jù)其實際的健壯性需求收集硬數(shù)據(jù),而不是事先對其進行過度設(shè)計。 不要像我一樣成為完美主義者,但也要對您的用戶和開發(fā)者同好。 如果您可以毫不費力地使您的應用程序更強大,那就去做吧。 如果需要更多工作,請去收集數(shù)據(jù)以證明(或不需要)該工作。
翻譯自: https://www.javacodegeeks.com/2013/09/simplicity-vs-robustness-demonstrated-on-lock-file-handling.html
怎么簡單的鎖定文件夾
總結(jié)
以上是生活随笔為你收集整理的怎么简单的锁定文件夹_简单性与鲁棒性–在锁定文件处理中展示的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 唱歌用英语怎么读 唱歌的英语是什么
- 下一篇: JDK语言功能预览:切换表达式