鱼生 的个人资料Thorje, Rakkas, Mishun 发...照片日志列表 工具 帮助

日志


3月5日

Jacob Part3

再接Part2
 
那我们的Sequence如何取回控制权呢?让我们再次回到channel的另一端——ML上。处理channel援引和MLVPU最重要的工作之一,SequenceParentScopeML实现如下:
class SEQUENCE extends ACTIVITY {
  ...
  private class ACTIVE extends BpelJacobRunnable {
    ....
    public void run() {
      ...
      object(new ParentScopeML(_child.parent) {
        public void compensate(OScope scope, SynchChannel ret) {
          _self.parent.compensate(scope,ret);
          instance(ACTIVE.this);
        }
 
        public void completed(FaultData faultData, Set<CompensationHandler> compensations) {
          HashSet<CompensationHandler> comps = new HashSet<CompensationHandler>(_compensations);
          comps.addAll(compensations);
          if (faultData != null || _terminateRequested || _remaining.size() <= 1) {
            _self.parent.completed(faultData, comps);
          } else /* !fault && ! terminateRequested && !remaining.isEmpty */ {
            ArrayList<OActivity> remaining = new ArrayList<OActivity>(_remaining);
            remaining.remove(0);
            instance(new SEQUENCE(_self, _scopeFrame, _linkFrame, remaining, comps));
          }
        }
      }));
    }
  }
  ...
}
completed()方法理所当然的会让这个方法执行起来,除非抛出了一个错误、请求了一个终端、没有子活动余留。身为乐观派,我们应当仔细检查以确认一切正常,在第二个例子中,remaining活动被移除,然后Sequence抽象回到了原来的位置,代码如下:
public void run() {
   final ActivityInfo child = new  ActivityInfo(genMonotonic(),
          _remaining.get(0),
          newChannel(TerminationChannel.class), newChannel(ParentScopeChannel.class));
   instance(createChild(child, _scopeFrame, _linkFrame));
   instance(new ACTIVE(child));
}
如上代码例示了下一个子活动抽象和另一个叫作ACTIVE的抽象。那么这个ACTIVE抽象到底是什么呢?他其实是一个用于持续跟随执行着的子活动的抽象,有点类似于PXE中基于所有容器(while, sequence, pick, ...即用于各种处理的活动抽象)的协议。那么一个ACTIVE(有时候也是WAITER)抽象主要照顾其子活动。
然后,我们例示了一个WHILE抽象,这是SEQUENCE的下一个子活动,So what happens there?
public void run() {
    boolean condResult = false;
    try {
      condResult = checkCondition();
    } catch (FaultException fe) {
      _self.parent.completed(createFault(fe.getQName(), _self.o),_compHandlers);
      return;
    }
    if (condResult) {
      ActivityInfo child = new ActivityInfo(genMonotonic(),
              getOWhile().activity,
              newChannel(TerminationChannel.class), newChannel(ParentScopeChannel.class));
      instance(createChild(child, _scopeFrame, _linkFrame));
      instance(new WAITER(child));
    } else /* stop. */ {
      _self.parent.completed(null, _compHandlers);
    }
  }
现在我们分析这些代码。第一步是评估WHILE状态。如果返回true,那么就创建一个子抽象,并且创建一个WAITER去跟踪他的执行。WAITER的实现如下,非常简单易懂:
private class WAITER extends BpelJacobRunnable {
    private ActivityInfo _child;
    private boolean _terminated;
 
    WAITER(ActivityInfo child) {
      _child = child;
    }
 
    public void run() {
      object(false, new TerminationML(_self.self) {
        public void terminate() {
          _terminated = true;
          _child.self.terminate();
          instance(WAITER.this);
        }
      }.or(new ParentScopeML(_child.parent) {
        public void compensate(OScope scope, SynchChannel ret) {
          _self.parent.compensate(scope,ret);
          instance(WAITER.this);
        }
        public void completed(FaultData faultData, Set<CompensationHandler> compensations) {
          _compHandlers.addAll(compensations);
          if (_terminated || faultData != null)
            _self.parent.completed(faultData, compensations);
          else
            instance(WHILE.this);
        }
      }));
    }
  }
终止符和补偿符(译者注:就是{这类标签/符号的另一半……)实际意义不大。例如SEQUENCE的完成(Completion),重新例示了WHILE抽象。这也展示我们处理循环的方法,即通过重新例示主WHILE抽象(再次评估状况,如果为真则创建子活动。)
 
最后,如果WHILE出现FALSE,那么他将通知其父channelSEQUENCE将来到最后的活动:REPLYREPLY回复各种可变的内容并通知他的父集,这就是REPLY的流程。然后我们就可以说这整个流程已经完成了!是的,我们成功了!

Jacob Part2

接Part1
 
Walking through examples
While
<process name="while1"
    targetNamespace="http://pxe/bpel/unit-test"
    xmlns:bpws="http://schemas.xmlsoap.org/ws/2003/03/business-process/"
    xmlns="http://schemas.xmlsoap.org/ws/2003/03/business-process/"
    xmlns:tns="http://pxe/bpel/unit-test"
    xmlns:xsd="http://www.w3.org/2001/XMLSchema"
    xmlns:test="http://pxe/bpel/unit-test.wsdl"
    suppressJoinFailure="yes">
   <partnerLinks>
      <partnerLink name="testPartnerLink"
         partnerLinkType="test:TestPartnerLinkType"
         myRole="me" />
   </partnerLinks>
 
   <variables>
     <variable name="var1" messageType="test:TestMessage2"/>
   </variables>
 
   <sequence>
       <receive
          createInstance="yes"
          name="startReceive"
          partnerLink="testPartnerLink"
          portType="test:TestPortType"
          operation="testOperation"
          variable="var1"/>
      <while condition="bpws:getVariableData('var1', 'TestPart') &lt; 10">
        <assign>
           <copy>
             <from expression="bpws:getVariableData('var1', 'TestPart') + 1"/>
             <to variable="var1" part="TestPart"/>
          </copy>
        </assign>
       </while>
       <reply name="endReply"
              operation="testOperation"
              partnerLink="testPartnerLink"
              portType="test:TestPortType"
              variable="var1"/>
   </sequence>
</process>
一切都从接收开始。所以我们首先从BpelProcess.PartnerLinkMyRoleImpl.inputMsgRcvd()开始讨论Jacob-focused。以下是重要的代码 (当信息到达实例的时候开始执行):
BpelRuntimeContextImpl instance = createRuntimeContext(newInstance, new PROCESS(_oprocess), messageExchange);
...
    // run the vpu
    instance.execute();
!BpelRuntimeContextImpl构造器中有如下代码:
if (PROCESS != null) {
   vpu.inject(PROCESS);
}
这里入了一个Process。当开始执行的时候,Process例示了他对其子活动的执行的控制范围,并且开始监听对消channel和完成channel。从process我们可以得到范围,然后是我们的主sequence,最后是我们的接收。
接收被映射到一个获取消息PICK上,因此其Jacob实现写在PICK中。PICK主要是分离出正确的相互关系,再选择合适的消息,然后等到消息。在实例中,我们对BpelRuntimeContextImpl .select() (and called by PICK)中的代码更感兴趣:
if (_instantiatingMessageExchange != null && _dao.getState() == ProcessState.STATE_READY) {
   for (int i = 0 ; i < correlators.size(); ++i) {
     CorrelatorDAO ci = correlators.get(i);
     if (ci.equals(_dao.getInstantiatingCorrelator())) {
       inputMsgMatch(pickResponseChannelStr, i, _instantiatingMessageExchange);
       return;
     }
   }
}
这里会调用类似如下的东西:
vpu.inject(new JacobRunnable() {
   public void run() {
      PickResponseChannel responseChannel = importChannel(responsechannel, PickResponseChannel.class);
      responseChannel.onRequestRcvd(idx, mex);
   }
});
这里就是真正开始的地方。当注入Process后,这个抽象会调用channelreceive的反应。该channel的另一端会作为一个MLPICK中实现。
object(false, new PickResponseML(_pickResponseChannel) {
    public void onRequestRcvd(int selectorIdx, Object msgex) {
        ...
      ActivityInfo child = new ActivityInfo(genMonotonic(), onMessage.activity, _self.self, _self.parent);
      instance(createChild(child,_scopeFrame,_linkFrame));
    }
});
此方法展示了receive必需做的事情(例如变量和相互关系的初始化等),并且创建子活动。当处理一个真实的PICK的时候,这个子活动应当处于获取消息活动,然而对于一个receive来说,这是个空活动。所以我们的receive完成了吗?事实上,子活动完成了。子活动才构造器中,我们传递了之前提供给的同一个ParentScopeML。因此当子活动完成的时候,会通知该receive的父活动,这就意味着receive自己本身并不需要去处理该问题。这样一个空活动就马上完成了:
_self.parent.completed(null, CompensationHandler.emptySet());
onRequestRcvd()方法结束后,会马上通知父序列。
 

Jacob Part1

Apache Ode关于Jacob的部分翻译。没地方放于是贴上来,各种疏漏请无视。
 
————————————————————————————翻译的胜利分割线
 
Main Jacob Concepts
 
Channels
如上所诉,channels是用于PXE引擎中活动的通信的接口。ChannelTerminationChannel, ParentScopeChannel or CompensationChannel几种。某些简单的channel能使所有活动在创建时就能与其环境相互作用。当一个活动想向其的父级通知他已结束,这个活动就会调用其父级TerminationChannel
Channels的实现由动态协议提供,主要在ChannelFactory中。
 
 
JacobObject / JacobRunnable
如果你不在乎细节的话,那么JacobObjectJacobRunnable就是方法的实现。当抽象执行的时候,这个方法就会执行。
一个JacobObject就是一个闭包。维基百科曰:“一个闭包是一组由特定文法环境约束的函数源码。闭包文法变量与全局变量的区别在于,他们并不出现在全局变量的名空间。他们区别与面向对象的对象变量在于,他们约束于方法,而不是对象。”
一般而言Java并不支持闭包,所以JacobObject尝试解决这个问题。但这并不是一个真正意义上的闭包,而只是使问题变得简单些。闭包在java中是静态编码的,但是在其他大多数语言支持的闭包是动态的。所以在Jacob中,一个闭包应当实现某些方法并提供其他公共方法以控制channel和复制自身。
JacobRunnable就是一个实现了run()方法的JacobObject。因为所有的活动都继承了JacobRunnable,因此这些活动都应当在这个run()方法中实现他们的主要处理。他们的初始化阶段在各自的构造器中完成。
 
Method Lists (MLs)
Method Lists 类可以看作是channel的另一端。当只调用一个channel方法的时候,他们并不会被援引,但一旦Jacob引擎把channel援引从其内部堆栈中顶出来,就会援引ML(此处能再次看到执行堆栈是如何被中止的)。
 
通常ML的实现在PXE中是内联的,因为这样比较容易在活动的run方法中申明。例如下面的Sequence例子:
void run() {
     ...
         // create an object to wait for the "completed()" notification
         // from the child activity.
         object(new CompletionChannelML(childCompletionChannel)) {
            void completed() {
               // Ok, finished with the child, create a runner
               // to do the next child.
               instance(new SequenceChildRunner(currentChild+1));
            }
         }
       }
}
这里的对象方法继承于JacobObject,这也是一个提交MLJacob的办法。因此该Jacob runtime就能匹配后面的channel消息。
 
VPU and ExecutionQueue
VPU是所有Jacob处理发生的地方。当一个JacobObject被注入VPU时,他实际上被认为是一个序列化(Continuation),该部分包裹了调用JacobObject并执行该序列的方法所包裹(在我们的实例中,这总是run方法,因为我们只处理JacobRunnable的实例)。
执行队列(ExecutionQueue,与其实现FastExecutionQueueImpl)是VPU管理的artifacts的容器,并且将这些artifacts组织成可pushpoo的队列形式,同时记录各项执行统计。
所以VPU的主要功能是从SOUP中出列一个回应(reaction),然后通过调用其抽象run方法来执行他(这个回应包裹了一个抽象)。就是这样。然而当JacobRunnable(通常是一个活动)被执行后,有可能发生一下事情:
  • 如果创建了别的抽象,他们就会插入回应队列;
  • 如果创建了新的channels,他们就会被保存起来留给以后使用;
  • 如果援引了channels,该信息将被保存起来以与新的ML匹配;
  • 如果创建了一个新的ML,那么他将被提交至VPU以尝试匹配一个channel援引。
VPU也负责维持其内部状态。因此当一个执行暂停(例如我们的过程有一个接收活动)的时候,VPU的状态将序列化并保存下来,日后再用。这个逻辑可以参考RuntimeContextImplexecute方法。
还有一点必需指出的是,ContinuationsJacobRunnable也是)不会“停留”在VPU队列中。他们只会POP出,执行。所以如果一个抽象要持续多于一个操作的时候,他会简单的做出选择(fork itself)。如此就解释了我们在Sequence例子中看到的:
instance(new SequenceChildRunner(currentChild+1));
这里简单的加入新的ChildRunner,将监视一下子对象的完成。如果你浏览一下PXE活动代码,就会发现像这样的一个例子会直接把一个同样的Jacob新抽象例子加入队列。
2月17日

续·花と飯 [有爱物小搜集]

深感第二次出现这title之硬把,不说废话,先上图。
 

  

经过俺的认真考证,此花应该大概仿佛有可能是矮牵牛(oioi,这认真你妹啊?)。此花插杆可活,可过冬,颜色丰富,生命力很是勥,花语也充满了爱意。
 
学名/拉丁名:Petunia hyhrida Vilm
英文名:Garden PetuniaCommon Garden Petunia
中文名:矮牵牛
别名:碧冬茄、杂种撞羽朝颜、灵芝牡丹、毽子花、矮喇叭、番薯花、撞羽朝颜
花语:有您在我心,与您同心,有您就觉得温馨
 
群众纷纷表示蛋蛋ED2神,连上ED1看更神,single3月初发售,另附avfun地址:http://222.243.146.200/html/music/20090119/18112.html
 
 
然后大家来一起唱咖喱之歌哦~(楼主其实很爱K歌,只可惜……
ps:为何美食剧总会出现类似梦遗大师之类的人出现……
ps:总觉得睡醒后有人会有来sm我的冲动?这感觉,已经不对。
10月27日

花と飯 [有爱物小搜集]

言:本人连福尔摩斯先生的1/10000都追不上,植物学糟糕得一塌糊涂,幸亏Google够强力,找到达人有爱考证文。然后很喜欢有个类似Hudson太太的好mm能变着花样陪俺解决五脏庙问题,俺很乐意帮忙的^^

 
 
——————————————————————————————————————————林氏盖饭分割线
 
 
转载自:光之大陆 作者:kagalin
 
刹那
 
 
 
中文名/日本海棠,贴梗海棠,木瓜花
 
日文名/寒木瓜(かんぼけ)
 
英名/Japanese quince
 
日本海棠为蔷薇科,木瓜属的植物。日本海棠,其花与贴梗海棠极相似,只是叶稍薄。其干多丛生,多分枝,枝上有疣状物突起,枝上有细刺。花色有大红和粉红色,花期3月至4月。每簇花由数朵组成,紧贴在枝上,艳丽妩媚。花后结球形果实,黄色,果径约3厘米。可植于庭院、路边、坡地,也常作盆栽,置阳台、室内观赏。这个花好像是贴梗海棠嫁接出来的品种
 
花言葉:熱情、平凡、早熟、妖精の輝き、魅感的な恋、他に、先駆者、指導者というのもありました。
 
花的象征语:热情,平凡,早熟,妖精的光辉,魅感觉性的恋爱,其他,说先驱者,领导人也有。
 
(鱼生:好吧,俺第一眼看成茶花了,果然差了十万八千里么……日本海棠,这傻那就是披着中东皮肤的某岛国国民嘛……)
 
 
 
提耶利亚
 
 
洋甘菊
 
カミツレ(カモミール)
 
Matricaria recutita
 
花言葉:逆境の中の活力、親交、仲直り 苦難の中での力?逆境に負けない強さ
 
  洋甘菊又名西洋甘菊、罗马洋甘菊、春黄菊,又被称为"大地的苹果"、“月亮之花”,原产于欧洲和西亚、北非等地。Chamomile一名就是源自希腊文,意为“大地的苹果”。事实上,不仅它的花具有强烈的苹果香,而且内含丰富的氨基酸、挥发油、黄酮类化合物、镁、钙、铁、锌等有益成分,如同苹果一样被民间视为温和且不具副作用的万能疗方。它还能使栽种在其四周的植物健康成长,所以还有“植物医生”的美称。洋甘菊以清凉、镇定、安眠的作用著称,温柔、纯净的特点使得它经常被人们与月亮联系在一起,是传说中的月亮之花。
 
(鱼生:左上是雏菊,右上的是洋甘菊。两者长得几乎一模一样但其实差很远……据wiki说,洋甘菊是“大地的苹果”,有苹果香,药用价值很高,而雏菊就比较普通……囧,这洋甘菊还是之前看图书馆战争学的。)
 
 
阿雷路亚
 
 
韩信草
 
タツナミソウ(立浪草)
 
Scutellaria indica
 
花言葉:私の命を捧げます
 
花的象征语:献上我的生命
 
韩信草为多年生草本。叶对生,叶卵状椭圆至线状披针形,花着生于叶腋,粉紫色。我国分布较广,华南、华东、台湾分布较多。野生的韩信草常见于田间、溪边及疏林下。因此,韩信草喜湿润、蔽荫或部分遮阴的环境条件下栽培,对土壤要求不严,以疏松肥沃的沙质壤土为宜。多用播种繁殖,发芽适温为1822℃,因种子较小,覆土要薄,1周左右发芽。生长前期可少量施用氮肥,开花前多施磷钾肥,以促进发棵及开花。因韩信草生长强健,少有病虫危害。韩信草多用于盆花及花坛栽培,也可用于风景园林及地栽。
 
(鱼生:献上我的生命,这这这这便当暗示?还是指哈雷……?)
 
 
莱尔
 
 
假昙花
 
イースターカクタス
 
Rhipsalidopsis gaertneri
 
花言葉:復活の喜び、熱情
 
花的象征语:复活的喜悦,热情
 
株高15厘米至20厘米,多分枝,叶已退化,枝呈茎节状悬垂。茎椭圆形,扁平、节状,青绿色,节侧圆波状或缺刻,圆齿腋部具短毛或少许黄色刚毛,与仙人指外形很相似,故又称“螃蟹花”。花筒短,花径6厘米至8厘米;花瓣伸展较广,是标准的辐射状花,花色橙红而鲜丽,通常在3月至4月开花,正值欧美国家的复活节,故又被称作“复活节仙人掌”。果实具5棱,长约1.5厘米。
 
(Epiphyllum oxypetalum)
 
花语:刹那的美丽与辉煌,一瞬即永恒。
 
(鱼生:原文的考证先生顺便给出了昙花……嗯嗯,挺称Lockon的。个人蛋痛再考证了假昙花和昙花的区别:假昙花,学名Rhipsalidopsisgaertner,别名连叶仙人掌、顶毛爪,为原产巴西的仙人掌科假昙花属多年生肉质植物。昙花,学名Epiphyllum oxypetalum,别名月下美人,为仙人掌科昙花属多年生半灌木状多浆植物。说白了昙花就是灌木而假昙花是就仙人掌而已。
 
 
王女
 
 
郁金香
 
チューリップ
 
Tulipa gesneriana
 
花言葉:永遠の愛情,愛の告白,思いやり,恋の告白,真面目な愛,誘惑,博愛,美しい瞳,名誉
 
黄色郁金香: 愛の表示,望みなき愛,名声,希望のない恋,正直,実らぬ恋,母の日
 
郁金香的花语:博爱、体贴、高雅、富贵、能干、聪颖。
 
黄郁金香:高雅、珍贵、财富、友谊,没有希望的爱,象征神圣、幸福与胜利
 
(鱼生:这年头,年上的越来越萌……)
 
 
 
——————————————————————————————————————————林氏盖饭分割线
 
 
 
最近翻日剧,《流行之绊》这个相当有爱。故事讲的是双亲惨遭杀害、背负着沉重命运的兄妹三人14年后对凶手复仇的故事。原著是个罗密欧与朱丽叶式的悲剧,TV却拍得欢乐无比,杀必死大放送。如果后面故事基调再180°的反成悲剧那这片就真的无敌了!
 
然后对片中提到的“ハヤシライス”很有兴趣,发现其实就是日式红酒烩牛肉饭,基本每家西餐厅都能找到,囧。这菜还算比较好做,哪天蛋痛了去搞材料弄弄……
 
材料:
牛肉、洋葱、蒜、砂糖、盐
酱汁:
小麦粉、黄油、月挂(翻译过来是这样,是月挂树的叶子还是什么的,没就算……)、昆布、红酒、番茄(大家看着放就是……)
 
1、 番茄去皮切碎,加入昆布汁,备用
2、  把黄油放入平底锅加热,慢慢加入小麦粉,一边搀和一边炒别弄焦,炒到褐色即可
3、  把番茄、月挂、昆布、红酒倒进去混合,文火煮他个半天,酱汁完成……
 
4、  洋葱切片。往锅里放一大汤匙左右的黄油,文火,马上放入蒜,稍微变色后加入洋葱
5、  洋葱炒到浅褐色是加入牛肉,继续炒,牛肉基本变色后加入之前弄好的酱汁,炖他5个小时,就好了……
6、  另外起锅做焦糖:放入砂糖,文火煮之,溶了变褐色即可
7、  然后来一勺那5小时炖制品……浇到焦糖上,加点胡椒粉和盐,搅拌均匀,即可配饭上碟
 
 
Done~!
 
求有爱人士试验之,好吃俺再自己弄弄(或者直接做好分俺一份……