10/25/2005

如何通信(2)

我所说的1和2的结合,就是全文比较和包含元操作的队列同步地结合,从服务器获得全文,在客户端merge,反方向则只用元操作的队列。
好处是可以保证服务器的version控制,需要重点考虑的还是merge的策略,目的是让客户端看不出来我正在同步中,至少不影响他的操作。
这样做似乎不需要写出一个cronExpression的js实现,减低了很多难度,而且符合了我eventItem和event是两个概念的需求。只需要同步的快点就行了。希望他在上不了网的时候少做一些什么重复性的设置。
队列,我的想法还是保存一个字符串的js数组,然后用反射去执行,队列不成功就不断重试好了
小有收获,实例化出来的两个queue竟然在使用同一个queue和remote,还没想明白为什么。这个attribute也没有final,static, transient让我选,可能是node的特殊性吧,为啥以前这么在view上就不会有这样的问题。所以,我干脆把他们做成两个node,反正他们的行 为和策略也不尽相同。
的确是很短小啊,我记得我当年写过一个connectionImpl,相应部分的java代码虽然严谨但是的确是非常难写的,我今天再看了一 次,那些notify然后到哪儿了我都说不清楚。不过感觉自己以前掌握的线程,锁,这些的应用还是很扎实的。嘿嘿(时隔一年就看不懂了)

为了在队列同步时尽量减少冗余的数据甚至频繁的远程访问,比如在summary上ontext的 时候希望更新currenteventDP,但是同样的会希望提交更改,可是这样的话每写一个字就多一个remotecall,即便是做出了负载平衡,但 是用户甚至保留页面至(操作数*interval)时间,简直十分荒唐。
所以我昨天添加了客户端产生uuid的方法,并且有了包装成js类送回服务器的通用包装类,这样的一个wrapEvent通过此uuid唯一认证,那么我更新了enqueue方法(见于上一entry)。splice掉了旧的还没有同步出去的内容。


10/24/2005

如何通信(1)

今天的计划是让新建任务面板中的是否是未安排任务的checkbox可以和event对象互动。
这个题目要求event的托拽可以影响checkbox的value,而点击checkbox,event也会产生托拽的效果。
这我以前似乎做过,但是认为是无解的命题了,无法避免无限循环。
还是calendar,让我看到了正确的设计。
很简单,通过
可以得到是否托拽改变了category,再让onclick去改变这个值。我也想不起来为啥以前没解决了。仿佛还有lazyreplication的问题吧。
不过,我认为其文档是有错误的,文档中说path相当于once语义。谁晓得是个always语义。
客户端街面上的操作,基本上做成了(去掉重复性,给别人布置==以后),但是还没有数据通信,我考虑了一下午,一样无解。
我规定了几个前提:
  • 用javarpc
  • 实现异步
  • 减少数据流量
  • 基于timestamp的version控制
有三种通信方式的念头:
  • 最蠢的和最简单的就是做全文比较,几秒钟用客户端数据和服务器比较一次,可以完全地做到异步,但是如何保证用户最后的操作也被异步同步了,呵呵……
  • 纪录每一次元操作,用什么特殊语句或者对象记录一下,放入队列中,然后让队列做异步同步。这种方法如果操作与操作之间有耦合、冲突、先后性的话,那还不如第一种,再说如何记录和分析命令,也是会比较晦涩的
  • 任何元操作都产生一个rpc命令,做完就做完了,这样在网络畅通的情况下可以保证客户端和服务器的数据一致性,也不用做什么比较和分析。如果不畅 通,有一个rpc没成功,那么两边就有分歧了。而且我刚刚在实践的时候,也发现,addEvent没办法简单保证立刻获得新丁的id,要么停滞下来等,要 么就得不到。不过这也是可以继续研究的,说不定有方法。

calendar源程序没有这一部分,但是做第一种的扩充是最简单的。

以前在"麦迪快"里,我用的是1和2地结合,把我折腾半死,当然,看起来还是不错的想法,只是中间问题多多。

烦!

10/20/2005

10-20

event的颜色以及可以附加在上边的eventselector的颜色,是由\\event\category\@value控制的,我添加了一个然后添加了一个新的style,果然好用。
这一种做法,我曾经在3C的项目中使用过,不过那时候并没有根据服务器的数据作改变。
event的选择颜色的做法也是很值得我学习的,
var gColorTable = {
green:{
dim: 0xCBD1C5,
bright: 0xD4DAC8,
bkgnd: 0x587457,
trans: {ra:85, ga:100, ba:85}
},
blue:{
dim: 0xBBC6D1,
bright: 0xC6CEDC,
bkgnd: 0x4C5E7E,
trans: {ra:75, ga:85, ba:100},
bvl_bkgnd: 0xCDD4E0,
bvl_hilite: 0xDFE4EB,
bvl_shdw: 0x606369
},
....
}
var category_colors = {
holiday: "green",
astro: "purple",
....
}
下午从addEvent(cal-data.lzx#138)方法开始研究,在197行处的
alleventsDP.addNodeFromPointer(blankeventDP);
发现这句话的前后currenteventDP从无数据到有数据。甚是不解。currentventDP在这一个文件中没有setDatapath,setFromPointer之类的赋值方法,搜索所有文件也没有发现这三个pointer之见有什么直接关系。
搜索currenteventDP发现,在eventselector的setSelectedEvent方法中有一句
currenteventDP.setFromPointer( e.datapath );
debug一下,果然这句话在currenteventDP发生改变的时候起了作用,而这个方法正是event的selected属性的setter方法中使用的。

// When a event is current it's selected node attribute is 'true'
// This is the only way that an event becomes the current event,
// which in turn selects the event selector bar
debug.write("sel", sel);
this.selected = sel;
if (this.selected)
eventselector.setSelectedEvent(this, this.mouseIsDown);
而event和alleventsDP指向同样的数据源。
哈终于被我发现了来龙去脉,这样写保证了currenteventDP始终是那个被选中的event的dp。

10/19/2005

10-19

昨天的问题已经通过过滤date而解决了,今天也实现了彻底的dnd,把应用在timeview上的vscrollbar也用在这上边了。
Z轴深度的问题还是没有解决,拖动的时候会让选中的event看起来跑到界外边,看起来很奇怪。
接下来想研究event.lzx,也许可以让event条看起来更生动。
我希望用颜色表示event的状态、类型、级别
日期的问题,我先前想错了,从服务器给客户端的只能是year,month,day,hour,min,sec几个值,这样做一方面可以很容易从xpath映射到对象上,不用中间写解析long值得问题,另一方面,假如某人设定了'8点中起床'的任务,不会因为时区改变而改变,变成NY的20点钟,etc,.
而另一种event也许是需要站在绝对时间的立场上考虑的,就是拿一个时刻点,不管你在那个时区,它离格林尼治时间就是那么多,这也是有可能的……
另一个更严重的问题是,如果服务器从中国搬到了美国,那么所有人的所有event都迟了或者遭了半天,……
所以我仍然有个想法是保存客户的timezone信息,而这个在我设计cronExpression的时候已经加进去了,后来还不知道是不是需要,如今看来是很需要的。
这样看来,用户的意念会有两种,相对的和绝对的,而绝对的需要知道设定此时间的确切时区或者timezoneOffset。
而客户请求的时候自然是要带着自身的timezone信息去请求的,如果是绝对的可以忽略此信息,而相对的就要使用此timezone耦合出用户需要的时间。
嗯……这样看似是可行的吧。那么需要决定这场计算的生命期,用户每秒钟绕地球7圈的话,哪一样是无解的命题。
要下班啦,明天想。

new Date(0)

向来只知道new Date(0)是1970年1月1日
今天在laszlo里写new Date(1970,0,1,0,0).getTime()却得到了-28800000的答案,一除,相差了8小时,心想这肯定是因为我们在+8时区了, 顿时很迷惑,到底该用new Date(0)还是new Date(1970,0,1,0,0)。
又在java里写了一个测试,果然,
Calendar cal = new GregorianCalendar();
cal.setTime(new Date(0));
assertEquals(1970, cal.get(Calendar.YEAR));
assertEquals(0, cal.get(Calendar.
MONTH));
assertEquals(1, cal.get(Calendar.DAY_OF_MONTH));
assertEquals(8, cal.get(Calendar.HOUR_OF_DAY));
assertEquals(0, cal.getTimeInMillis());
Calendar cal2 = new GregorianCalendar(1970, 0, 1, 0, 0, 0);
assertEqual(0, cal2.getTimeInMillis() + cal2.get(Calendar.ZONE_OFFSE));
想想也对,Date是带着TimeZone信息的,而这个时间0点又不能因为地区的不同而有不同的含义,嗯……这下认识到了
在laszlo中的写法就是
var tempt=new Date(1970, 0, 1);
if (tempt.getTime()==tempt.getTimezoneOffset()*60000);
而我想,在我需要的这个地方还是用0比较好,而不是各个地区的"0"。

10/17/2005

10-17

周一的早上是最最痛苦的,被拖着拽着起了床,到了办公室眼睛才睁开了30%
晨会上经理问我这周都做了啥,我又是要想好一阵,结果还是没有说全。
看来还是有必要记录一下
今天上午修正了buzzbar的两个错误,
1货主为空时编号dataset没有清空,2货主的datapath增加了排序特性,这样""在第一个了。
嗯,对了,还有一个错误,就是roll(Calendar.DATE_OF_MONTH,-31)的错误,如果小月的次月1日那就会跳过啦,一会儿改一下。
还修正了Ant脚本的一个错误,
关于用Ant作war->upload to ftp->telnet and restart tomcat,仿佛在服务器上执行有效率问题尤其是服务器的回响是中文的,在Ant上根本看不懂,于是在自己机器上写了一个 build_test.properties反复运行了几十次,应该是没问题了。改了xmxxms都到512,可能不会内存溢出了,再溢就是某某写的有问 题了
Event系统在开始重新阅读我自己写的代码,做了些重构,优化了一些在选择人物的时候的一些操作方式。
下午准备能研究一下dnd,保证datapath更新。

10/10/2005

PersistentEnum

新项目自然要有新念头。
捧着上个月月初写下的UML类图,满头的问号,仿照Workflow做的Step,又是Privilege,Request上还画了一个1..1的自相关,最恐怖的要数MessageStrategy。唯一记得的,是花了N长时间弄得CronExpresstion。
先把UML重构一把,涂上醒目的颜色,心里清楚了一些,有两个族需要做subclass,可是又超过6个类是表示状态的Enum。
5分钟搞定类结构和hbm.xml,突然对PersistentEnum钟情起来,因为之前也是各处出现的这种东西要么就做成static final了,要么做成类型安全枚举了,有的还给出了ResouceBundle弄了些中文。但是,持久的一点花头都没有,int,String无出其右。写了那么多注释也对安全毫无帮助。
Hibernate2.1上
package net.sf.hibernate;
/**
* Implementors of PersistentEnum are enumerated types persisted to
* the database as SMALLINTs. As well as implementing toInt(),
* a PersistentEnum must also provide a static method with the
* signature:

*

* public static PersistentEnum fromInt(int i)
*
* @author Gavin King
* @deprecated Support for PersistentEnums will be removed in 2.2
*/
public interface PersistentEnum {
public int toInt();
}
reference上让这么用,但是明摆着不想让人用好,找了好一会儿,看javaeye去年也有人讨论这deprecate的方法怎么绕,UserType我以前也写过就是没写过Enum的,而且那次的记忆完全是灰色的。
找到了一篇hibernate上的doc 改了一下,仿佛可用?
嗯……开始玩测试驱动吧,写了一个测试,run,run,...run.
去掉了发现的30来个错误,最后变绿了,哈哈
太好了,int,String这么缺乏表达力的东西终于可以说88了,而且这样写出的类型安全枚举十分的干净。不错不错