adflight.cpp现在有个多线程的问题, 如果在UpdateImpression()中刚执行完statement->ExecCommit(); 操作后, 在下面的Load()函数的 Auto_WriteLock autoWLock(m_RWLock);之前, 还是有一点时间可能有其他线程完成了Targeting函数的m_nImpressioned++操作, 这个就没记入到数据库里了......
[2001-8-3 9:04:13] Hello Monkey:
呵呵...你看的应该是舊的版本...那个版本是否从数据库读出impression放入內存中?
现在改為0了...以相对数表示, update时用set impression=impress+n的形式表示...
[2001-8-3 9:05:41] Hello Monkey:
我update了...麻烦你幫我看看...hehe...
另外, 我都担手会有多綫程问题..尤其是在refresh时的updateimpression和load之间....我还在考慮...
[2001-8-3 9:06:49] wooce:
我看的就是这个啊, 我就是说set impression=impress+n的这个n可能在UpdateImpression()和Load()之间的时间可能漏了一些发送次数.
[2001-8-3 9:07:12] Hello Monkey:
OH...明白了...thx
[2001-8-3 9:09:01] Hello Monkey:
其实我之前我想过在refresh中加锁...不过因為不肯定是否有问题...所以沒加...
你有什麼建议?
[2001-8-3 9:15:40] wooce:
就跟你先前想的, 在adflight_auto_refresh里UpdateImpression()之前加上IAuto_WriteLock autoWLock(m_RWLock);
这样的线性Cache结构下似乎只能这样了.... sigh.
[2001-8-3 9:16:43] Hello Monkey:
有沒有更好的cache結构?
[2001-8-3 9:21:12] wooce:
现在你在AdServ里的Cache也无所谓不好, 一股脑全Cache进去, 比较简单.....
[2001-8-3 9:22:50] wooce:
+_%d
%d前面的下划线是在IncoreDb类库里定义的吗?
[2001-8-3 9:37:49] Hello Monkey:
因為想到每次cache其实都要掃一次, 所以就这样了...
我想可不可以把updateimpression放入load里...
[2001-8-3 9:38:48] Hello Monkey:
no this _ ar...
[2001-8-3 9:40:53] wooce:
当然可以啊, 不过Load()函数中的AutoWLock就要提到前头.
then the "_" is perhaps wrong typing.....
[2001-8-3 9:46:55] Hello Monkey:
yes...the new version even has no space....
[2001-8-3 9:47:14] wooce:
如果内存充足的话, refresh的时候把数据库中的先读到另一个IListNode
[2001-8-3 9:47:32] Hello Monkey:
主要是不知道updateimpression和load是不是都会同时做...
[2001-8-3 9:48:38] Hello Monkey:
这就降低了数据库的效率影响...也不錯喔...
--------------------------------------------------------------------------------
[2001-8-14 3:33:39] wooce:
现在放在tblib_new里的ihashcache旧了一点, 我上星期五对它再做了些修改提高效率(更新FetchAndCache函数, 开始只加读锁, 确认在Cache中没有的时候各线程用TryWriteLock函数抢占写锁, 先抢到的进入从数据库读取入Cache的操作, 其他线程则通过申请读锁等待它完成后再从Cache里读) , 你到clearcase里看看.
[2001-8-14 3:36:18] Hello Monkey:
ok...
[2001-8-14 3:36:58] wooce:
另外, 我对irefcounter.cpp/.h 也做了点修改, 加了一个SubReference函数, 刚才Rayman说已经merge进去了, 而我看到\pumauploadtblib_new里的还是旧的.
[2001-8-14 3:38:58] wooce:
你得把这两个merge进去, 我才能在programAdStorage目录下删除irefcounter.cpp/.h这两个文件......
[2001-8-14 3:38:58] Hello Monkey:
你的新函数放在那里?
[2001-8-14 3:39:17] Hello Monkey:
ok
[2001-8-14 3:42:11] Hello Monkey:
subreference函数有什麼用的?
[2001-8-14 3:44:32] wooce:
我要把Cache的访问计数记到数据库里, 在数据库里update adletter set visited=visited+%d .... counter.GetReference() 成功以后, 就要在IRefCounter类里减去相应的数........
[2001-8-14 3:47:36] Hello Monkey:
这一步加入refcounter中好嗎?
好像比較怪.....有沒有更好的办法?
[2001-8-14 3:52:55] wooce:
加入这个函数又没什么损失.... 如果从把Cache中的计数记入数据库的角度看, 一点也不怪, 因为在数据库执行update操作的权限, 可能另有其他线程又把IRefCounter的计数增加了, 所以如果只加一个Clear()函数把计数值清零的做法可能会不正确的, 必须加一个SubReference函数在数据库Update成功之后再减计数值.....
[2001-8-14 3:58:51] Hello Monkey:
是的..如果从把Cache中的计数记入数据库的角度看, 一点也不怪, 但是好像这种情況比較特殊...換言之..这个函数只是為了实现现在所需的功能而加的, 以一个类库的角度看就有点怪了...如果这个功能能夠包在storage server中, 与irefcounter相对分離....好像合理一点吧...
[2001-8-14 4:03:57] wooce:
ILock m_RefLock; 是protected的, 只有定义IRefCounter类的子类才能访问它.... 定义它的子类不如直接把这个功能包进去了. 除了AdStorage还可能有其他应用程序会用到这个功能的....
[2001-8-14 4:06:07] Hello Monkey:
ok, 但是有sub应该有add....如果要加入库中, 最好把addrefernce也加进去....
[2001-8-14 4:06:59] wooce:
ok.... 当然还可以再加清0的Clear()函数....
[2001-8-14 4:09:35] Hello Monkey:
那我先不merge irefcounter啦...等加进去后再一次过merge, ok?
[2001-8-14 4:10:14] wooce:
ok.... 几分钟的事了....
[2001-8-14 4:10:22] Hello Monkey:
ok
[2001-8-14 4:12:21] Hello Monkey:
在ihashcache的fetchandcache中, 是不是在getcacheobject前必定要先申请到写锁?
[2001-8-14 4:17:01] wooce:
这个是肯定的了, 因为getcacheobject是要被重载来从其他地方如Database等取出object的, 需要避免你以前说过的多个线程可能同时都在Cache中找不到object, 然后同时去访问数据库取object的问题..... 但可以采用TryWriteLock的技巧使pNode = SearchNode(Key)在Cache中找Object前只须加读锁.....
[2001-8-14 4:24:01] Hello Monkey:
oh...明白了....
--------------------------------------------------------------------------------
[2001-8-14 9:07:31] wooce:
Box的旧的通讯协议:
(“Cmd”, 0x0002)
(“MID”, String)
这里有没有把"Cmd"这个字符串也一起在socket里发过来? 我看到似乎是没有的.....
[2001-8-14 9:24:25] Hello Monkey:
yes, 那个cmd只是在傳送前用而已...不会傳輸的...忘了注釋入文档中...hehe..
[2001-8-14 10:51:44] wooce:
除了"Cmd","Result"等, “RetCode” , “ErrCode” 等也一样不会传这些字符串本身吧, 即都只传值, 而不传键.
[2001-8-14 10:51:56] Hello Monkey:
yes...
[2001-8-14 10:52:24] wooce:
那你现在的文档说得还不是很清楚....
[2001-8-14 10:53:35] Hello Monkey:
ok, 那我再加一点...
--------------------------------------------------------------------------------
[2001-8-22 5:49:02] Hello Monkey:
你有沒有跟踪过basicflight的建构函数?
它好像沒有走进adflight和systemflight的init函数中.....卻走入了basicflight的init函数....
[2001-8-22 5:50:44] wooce:
oh, I forgot to add "virtual" before "void Refresh()" in adflight.cpp, etc,
[2001-8-22 5:51:05] Hello Monkey:
不, 是建构時的问题....
[2001-8-22 5:52:49] Hello Monkey:
好像利用:parent constructor的方式使父在执行建构函数時沒有执行指向子的virutal函数....
[2001-8-22 6:04:29] wooce:
maybe we should cut Init() function from the constructor in BasicFlight class.....
[2001-8-22 6:06:41] Hello Monkey:
but if we cut init(), some problem may occurs...
if refresh timout is less and when it was invoked, init() in the subclass wasn't invoked, then the refresh process will fail...
[2001-8-22 6:09:22] wooce:
把Init()函数从虚函数改成纯虚函数.....
[2001-8-22 6:10:14] Hello Monkey:
我试试, 看看有沒有不同....
[2001-8-22 6:13:41] Hello Monkey:
不行....慘....
[2001-8-22 6:14:30] wooce:
还是不会去执行adflight.cpp的Init()函数?
[2001-8-22 6:15:42] Hello Monkey:
不能是純虛函数....unresolve....
可能在constructor中不能用虛函数?
[2001-8-22 6:22:08] wooce:
应该是没法在父类的构造函数里调用指向子类的虚函数了...
把现在BasicFlight的构造函数中的内容全搬进一个Init()函数, 原来的Init()的名字改成OnInit(), adflight和systemflight的Init()也相应改成OnInit().... 应该只能这样解决了.
[2001-8-22 6:40:31] Hello Monkey:
有exception了....好像更差....
[2001-8-22 6:41:18] wooce:
?? 什么Exception?
[2001-8-22 6:41:59] Hello Monkey:
它在调用onInit時有exception, 但卻沒走到adflight和systemflight的oninit里面....
[2001-8-22 6:45:36] wooce:
basicflight.cpp里的Init()函数必须是virtual的啊?
[2001-8-22 6:47:55] Hello Monkey:
我改成这样:
由BasicFlight的建构函数立即调用init, 把原來在建构函数的東西全放了入init中, 然后init又调用純虛函数OnInit...
这里init要virtual?
[2001-8-22 7:01:36] wooce:
还是把basicflight的建构函数设为空吧, 在ADServSvr::ADServSvr()里new了各个adflight和systemflight后再分别调用其Init()函数.....
[2001-8-22 7:03:20] Hello Monkey:
又试试吧....
[2001-8-22 7:14:47] Hello Monkey:
改了, 但sql语句有錯...MySQL : Unknown column 'flight_no'
[2001-8-22 7:16:17] wooce:
把现在的SQL语句给我看?
[2001-8-22 7:20:35] Hello Monkey:
第一句...
select * from %s,%s where where %s.mid=%s.mid
and disabled=0 and start_date<=now() and end_date>=now()
and impression_goal>impressioned",
[2001-8-22 7:20:51] Hello Monkey:
第二句.
update %s set impressioned=impressioned+%d where flight_no=%d
[2001-8-22 7:23:28] wooce:
oh, am_system_flight表里是system_flight_no而不是flight_no, 你在systemflight.cpp里的第二句update里得写system_flight_no而不是flight_no
[2001-8-22 8:07:10] Hello Monkey:
你现在有沒有測试adserving的程序?
[2001-8-22 8:07:24] wooce:
没有.
[2001-8-22 8:07:38] Hello Monkey:
这是我现在的sql语句, 对不对?
select * from %s,%s where %s.mid=%s.mid and disabled=0 and start_date<=now() and end_date>=now() and impression_goal>impressioned
[2001-8-22 8:08:21] Hello Monkey:
那样的话adserving是不是还未測试?
[2001-8-22 8:09:23] wooce:
这SQL语句看起来没什么错误, 不过now()是mysql支持的函数, oracle可能就不支持.
[2001-8-22 8:10:10] wooce:
agree, adserving server我未做过功能上的测试.
[2001-8-22 8:28:45] Hello Monkey:
在attrconvert中沒有virtual constructor...
[2001-8-22 8:29:41] wooce:
? 不需要吧? 你编译不通过?
[2001-8-22 8:30:18] Hello Monkey:
有驚告, 而且出现很多...
attrconvert.cpp:4: unknown escape sequence: `' followed by char code 0xd
attrconvert.cpp:5: unknown escape sequence: `' followed by char code 0xd
....
...
[2001-8-22 8:31:28] Hello Monkey:
你可以编译通过?
[2001-8-22 8:32:09] wooce:
oh, 我只是在开头的const IString& coremailAttrTable =
下面每一行的结尾用来连接下一行而已, 编译没任何问题呀.
[2001-8-22 8:32:43] Hello Monkey:
但是我那边有呀...还很多...因為在那文件中很多号...
[2001-8-22 8:33:23] wooce:
怪了.
[2001-8-22 8:37:05] Hello Monkey:
因為每行都有个^M, 所以不行....
[2001-8-22 8:40:32] wooce:
oh, 我只在VC下编译, 所以没问题.
你在unix下编译时, 将attrconvert.cpp用UltraEdit的转换为UNIX格式的功能转换, 或者直接在命令行敲
cat attrconvert.cpp|tr -d '15'>attrconvert-unix.cpp
转换就行了.
[2001-8-22 8:41:34] Hello Monkey:
ok....