摘要:本文首發(fā)于泊浮目的專欄在語言中,有一個(gè)關(guān)鍵字叫做其作用是在函數(shù)前執(zhí)行。一般有兩種用法在該函數(shù)拋出異常時(shí)執(zhí)行。在該函數(shù)返回前執(zhí)行。這里的放入來自系統(tǒng)啟動(dòng)時(shí)利用反射所做的一個(gè)行為。因此并不會(huì)影響使用時(shí)的性能。
本文首發(fā)于泊浮目的專欄:https://segmentfault.com/blog...
在Go語言中,有一個(gè)關(guān)鍵字叫做defer——其作用是在函數(shù)return前執(zhí)行。在ZStack中也有類似的工具類,讓我們來看看吧。
演示代碼private void handle(APICreateInstanceOfferingMsg msg) { APICreateInstanceOfferingEvent evt = new APICreateInstanceOfferingEvent(msg.getId()); String type = msg.getType() == null ? UserVmInstanceOfferingFactory.type.toString() : msg.getType(); InstanceOfferingFactory f = getInstanceOfferingFactory(type); InstanceOfferingVO vo = new InstanceOfferingVO(); if (msg.getResourceUuid() != null) { vo.setUuid(msg.getResourceUuid()); } else { vo.setUuid(Platform.getUuid()); } HostAllocatorStrategyType allocType = msg.getAllocatorStrategy() == null ? HostAllocatorStrategyType .valueOf(HostAllocatorConstant.LEAST_VM_PREFERRED_HOST_ALLOCATOR_STRATEGY_TYPE) : HostAllocatorStrategyType.valueOf(msg.getAllocatorStrategy()); vo.setAllocatorStrategy(allocType.toString()); vo.setName(msg.getName()); vo.setCpuNum(msg.getCpuNum()); vo.setCpuSpeed(msg.getCpuSpeed()); vo.setDescription(msg.getDescription()); vo.setState(InstanceOfferingState.Enabled); vo.setMemorySize(msg.getMemorySize()); vo.setDuration(InstanceOfferingDuration.Permanent); vo.setType(type); InstanceOfferingInventory inv = new SQLBatchWithReturn() { @Override @Deferred protected InstanceOfferingInventory scripts() { Defer.guard(() -> dbf.remove(vo)); InstanceOfferingInventory inv = f.createInstanceOffering(vo, msg); acntMgr.createAccountResourceRef(msg.getSession().getAccountUuid(), vo.getUuid(), InstanceOfferingVO.class); tagMgr.createTagsFromAPICreateMessage(msg, vo.getUuid(), InstanceOfferingVO.class.getSimpleName()); return inv; } }.execute(); evt.setInventory(inv); bus.publish(evt); logger.debug("Successfully added instance offering: " + printer.print(inv)); }
這段代碼是ZStack ManageNode(簡稱MN)在接收到創(chuàng)建計(jì)算規(guī)格的請(qǐng)求后的處理邏輯,大致的邏輯即:
在DB中創(chuàng)建一條記錄
添加當(dāng)前賬戶與該計(jì)算規(guī)格的關(guān)聯(lián)
創(chuàng)建相應(yīng)的系統(tǒng)標(biāo)簽
回復(fù)該消息,并打印一行l(wèi)og
在這段代碼中,我們可以看到在執(zhí)行邏輯2、3時(shí),這里做了一個(gè)Defer.guard(() -> dbf.remove(vo));,其作用是在執(zhí)行下面的邏輯發(fā)生異常時(shí)執(zhí)行,這樣就移除了臟數(shù)據(jù)。
如何使用Defer的使用方法也很簡單,如果你要在某個(gè)函數(shù)使用它,在上面添加一個(gè) @Deferred的Annotation,然后就可以在該函數(shù)內(nèi)使用它了。
一般有兩種用法:
Defer.guard:在該函數(shù)拋出異常時(shí)執(zhí)行Runable。
Defer.defer:在該函數(shù)返回前執(zhí)行。我們可以使用其釋放局部鎖。
為了避免不熟悉ZStack讀者理解起來生澀,建議參考其Case在這里,我們將展現(xiàn)一個(gè)較為簡單的case:
public class TestDefer1 { CLogger logger = Utils.getLogger(TestDefer1.class); int count = 0; @Before public void setUp() throws Exception { } @Deferred private void case1() { count++; Defer.guard(new Runnable() { //當(dāng)捕捉到異常時(shí),執(zhí)行其中的匿名Runable語句 @Override public void run() { count--; } }); //拋出一個(gè)異常 throw new CloudRuntimeException("Roll back count"); } @Test(expected = CloudRuntimeException.class) public void test() { case1(); Assert.assertEquals(0, count); } }實(shí)現(xiàn)
Defer的庫非常的小。其本質(zhì)通過對(duì)Spring提供的AOP和Java提供的ThreadLocal以及一個(gè)Stack數(shù)據(jù)結(jié)構(gòu)進(jìn)行封裝:對(duì)于執(zhí)行函數(shù)的當(dāng)前線程存入一個(gè)Stack數(shù)據(jù)結(jié)構(gòu),每一個(gè)填寫在Defer中的Runable都會(huì)被放入,之后根據(jù)調(diào)用的Defer的函數(shù)來決定其行為。
這里Runable的放入來自系統(tǒng)啟動(dòng)時(shí)利用反射所做的一個(gè)行為。因此并不會(huì)影響使用時(shí)的性能。
文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請(qǐng)注明本文地址:http://m.specialneedsforspecialkids.com/yun/25203.html
摘要:本文首發(fā)于泊浮目的專欄在語言中,有一個(gè)關(guān)鍵字叫做其作用是在函數(shù)前執(zhí)行。一般有兩種用法在該函數(shù)拋出異常時(shí)執(zhí)行。在該函數(shù)返回前執(zhí)行。這里的放入來自系統(tǒng)啟動(dòng)時(shí)利用反射所做的一個(gè)行為。因此并不會(huì)影響使用時(shí)的性能。 本文首發(fā)于泊浮目的專欄:https://segmentfault.com/blog... 在Go語言中,有一個(gè)關(guān)鍵字叫做defer——其作用是在函數(shù)return前執(zhí)行。在ZStac...
摘要:每個(gè)消息都會(huì)被一個(gè)線程消費(fèi),同時(shí)最大并發(fā)量為。然后提交一個(gè)任務(wù)到線程池中,這個(gè)任務(wù)的內(nèi)容是從等待隊(duì)列中取出一個(gè),如果等待隊(duì)列為空,則刪除這個(gè)等待隊(duì)列的。小結(jié)本文分析了的久經(jīng)生產(chǎn)考驗(yàn)的核心組件線程池。 本文首發(fā)于泊浮目的專欄:https://segmentfault.com/blog... 前言 在ZStack中,最基本的執(zhí)行單位不僅僅是一個(gè)函數(shù),也可以是一個(gè)任務(wù)(Task。其本質(zhì)實(shí)現(xiàn)...
摘要:但在實(shí)際的二次開發(fā)中,這些做法未必能夠完全滿足需求。在源碼剖析之核心庫鑒賞一文中,我們了解到是的基礎(chǔ)設(shè)施之一,同時(shí)也允許通過顯示聲明的方式來聲明。同理,一些也可以使用繼承進(jìn)行擴(kuò)展。 本文首發(fā)于泊浮目的專欄:https://segmentfault.com/blog... 前言 在ZStack博文-5.通用插件系統(tǒng)中,官方提出了幾個(gè)較為經(jīng)典的擴(kuò)展方式。但在實(shí)際的二次開發(fā)中,這些做法未必...
摘要:下面將開始分析它的源碼。僅僅定義了一個(gè)最小應(yīng)有的行為。更好的選擇由于該庫是為定制而生,故此有一些防御性判斷,源碼顯得略為。 本文首發(fā)于泊浮目的專欄:https://segmentfault.com/blog... 前言 在ZStack(或者說產(chǎn)品化的IaaS軟件)中的任務(wù)通常有很長的執(zhí)行路徑,錯(cuò)誤可能發(fā)生在路徑的任意一處。為了保證系統(tǒng)的正確性,需提供一種較為完善的回滾機(jī)制——在ZSt...
摘要:但新增模塊的結(jié)構(gòu)卻還是大致相同,此即是的經(jīng)典設(shè)計(jì)模式這套模式也被開發(fā)者稱為三駕馬車。領(lǐng)域?qū)佣x負(fù)責(zé)表達(dá)業(yè)務(wù)概念,業(yè)務(wù)狀態(tài)信息以及業(yè)務(wù)規(guī)則。 本文首發(fā)于泊浮目的專欄:https://segmentfault.com/blog... 前言 隨著ZStack的版本迭代,其可以掌管的資源也越來越多。但新增模塊的結(jié)構(gòu)卻還是大致相同,此即是ZStack的經(jīng)典設(shè)計(jì)模式——這套模式也被開發(fā)者稱為ZS...
閱讀 2818·2023-04-25 22:51
閱讀 2057·2021-10-11 10:58
閱讀 3316·2019-08-30 10:49
閱讀 1877·2019-08-29 17:09
閱讀 3141·2019-08-29 10:55
閱讀 847·2019-08-26 10:34
閱讀 3492·2019-08-23 17:54
閱讀 985·2019-08-23 16:06