国产xxxx99真实实拍_久久不雅视频_高清韩国a级特黄毛片_嗯老师别我我受不了了小说

資訊專欄INFORMATION COLUMN

ZStack源碼剖析之核心庫鑒賞——Defer

ymyang / 818人閱讀

摘要:本文首發于泊浮目的專欄在語言中,有一個關鍵字叫做其作用是在函數前執行。一般有兩種用法在該函數拋出異常時執行。在該函數返回前執行。這里的放入來自系統啟動時利用反射所做的一個行為。因此并不會影響使用時的性能。

本文首發于泊浮目的專欄:https://segmentfault.com/blog...

在Go語言中,有一個關鍵字叫做defer——其作用是在函數return前執行。在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)在接收到創建計算規格的請求后的處理邏輯,大致的邏輯即:

在DB中創建一條記錄

添加當前賬戶與該計算規格的關聯

創建相應的系統標簽

回復該消息,并打印一行log

在這段代碼中,我們可以看到在執行邏輯2、3時,這里做了一個Defer.guard(() -> dbf.remove(vo));,其作用是在執行下面的邏輯發生異常時執行,這樣就移除了臟數據。

如何使用

Defer的使用方法也很簡單,如果你要在某個函數使用它,在上面添加一個 @Deferred的Annotation,然后就可以在該函數內使用它了。

一般有兩種用法:

Defer.guard:在該函數拋出異常時執行Runable。

Defer.defer:在該函數返回前執行。我們可以使用其釋放局部鎖。

為了避免不熟悉ZStack讀者理解起來生澀,建議參考其Case在這里,我們將展現一個較為簡單的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() { //當捕捉到異常時,執行其中的匿名Runable語句
            @Override
            public void run() {
                count--;
            }
        });
        //拋出一個異常
        throw new CloudRuntimeException("Roll back count");
    }

    @Test(expected = CloudRuntimeException.class)
    public void test() {
        case1();
        Assert.assertEquals(0, count);
    }
}
實現

Defer的庫非常的小。其本質通過對Spring提供的AOP和Java提供的ThreadLocal以及一個Stack數據結構進行封裝:對于執行函數的當前線程存入一個Stack數據結構,每一個填寫在Defer中的Runable都會被放入,之后根據調用的Defer的函數來決定其行為。

這里Runable的放入來自系統啟動時利用反射所做的一個行為。因此并不會影響使用時的性能。

文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。

轉載請注明本文地址:http://specialneedsforspecialkids.com/yun/25203.html

相關文章

  • ZStack源碼剖析核心鑒賞——Defer

    摘要:本文首發于泊浮目的專欄在語言中,有一個關鍵字叫做其作用是在函數前執行。一般有兩種用法在該函數拋出異常時執行。在該函數返回前執行。這里的放入來自系統啟動時利用反射所做的一個行為。因此并不會影響使用時的性能。 本文首發于泊浮目的專欄:https://segmentfault.com/blog... 在Go語言中,有一個關鍵字叫做defer——其作用是在函數return前執行。在ZStac...

    DevWiki 評論0 收藏0
  • ZStack源碼剖析核心鑒賞——ThreadFacade

    摘要:每個消息都會被一個線程消費,同時最大并發量為。然后提交一個任務到線程池中,這個任務的內容是從等待隊列中取出一個,如果等待隊列為空,則刪除這個等待隊列的。小結本文分析了的久經生產考驗的核心組件線程池。 本文首發于泊浮目的專欄:https://segmentfault.com/blog... 前言 在ZStack中,最基本的執行單位不僅僅是一個函數,也可以是一個任務(Task。其本質實現...

    enali 評論0 收藏0
  • ZStack源碼剖析二次開發——可擴展框架

    摘要:但在實際的二次開發中,這些做法未必能夠完全滿足需求。在源碼剖析之核心庫鑒賞一文中,我們了解到是的基礎設施之一,同時也允許通過顯示聲明的方式來聲明。同理,一些也可以使用繼承進行擴展。 本文首發于泊浮目的專欄:https://segmentfault.com/blog... 前言 在ZStack博文-5.通用插件系統中,官方提出了幾個較為經典的擴展方式。但在實際的二次開發中,這些做法未必...

    lolomaco 評論0 收藏0
  • ZStack源碼剖析核心鑒賞——FlowChain

    摘要:下面將開始分析它的源碼。僅僅定義了一個最小應有的行為。更好的選擇由于該庫是為定制而生,故此有一些防御性判斷,源碼顯得略為。 本文首發于泊浮目的專欄:https://segmentfault.com/blog... 前言 在ZStack(或者說產品化的IaaS軟件)中的任務通常有很長的執行路徑,錯誤可能發生在路徑的任意一處。為了保證系統的正確性,需提供一種較為完善的回滾機制——在ZSt...

    yintaolaowanzi 評論0 收藏0
  • ZStack源碼剖析設計模式鑒賞——三駕馬車

    摘要:但新增模塊的結構卻還是大致相同,此即是的經典設計模式這套模式也被開發者稱為三駕馬車。領域層定義負責表達業務概念,業務狀態信息以及業務規則。 本文首發于泊浮目的專欄:https://segmentfault.com/blog... 前言 隨著ZStack的版本迭代,其可以掌管的資源也越來越多。但新增模塊的結構卻還是大致相同,此即是ZStack的經典設計模式——這套模式也被開發者稱為ZS...

    honhon 評論0 收藏0

發表評論

0條評論

ymyang

|高級講師

TA的文章

閱讀更多
最新活動
閱讀需要支付1元查看
<