Make message interaction more readable, by using c++ local class:::: c++ local class: http://publib.boulder.ibm.com/infocenter/lnxpcomp/v8v101/index.jsp?topic=%2Fcom.ibm.xlcpp8l.doc%2Flanguage%2Fref%2Fcplr062.htm ///////////////////////////////////////////////////////////////////////////// #include <iostream> #include <map> using namespace std; #define MESSAGE_SEND 3 #define MESSAGE_TIME_OUT 4 #define MESSAGE_RESPONSE 5 ///////////////////////////////////////////////////////////////////////////// struct Worker { virtual void operator()() = 0; }; ///////////////////////////////////////////////////////////////////////////// struct HandlerPool { void addMsg(int msg, Worker& a) { maps[msg] = &a; } void run(int msg) { if (maps.find(msg) != maps.end()) { (*maps[msg])(); } else { cout << "no handler" << endl; } } map<int, Worker*> maps; }; HandlerPool g_handlePool; ///////////////////////////////////////////////////////////////////////////// #define if_on_msg(msg) IF_ON_MSG(onMsg_##msg) #define IF_ON_MSG(msg_handler_class) \ static struct msg_handler_class : Worker { \ void operator()() #define end_if_on_msg(msg) END_IF_ON_MSG(msg, onMsg_##msg##_handler) #define END_IF_ON_MSG(msg, handler_instance_name) \ } handler_instance_name; \ g_handlePool.addMsg(msg, handler_instance_name) ///////////////////////////////////////////////////////////////////////////// struct Worker_Before_refactor : Worker { void processMsg(/*const Message& msg*/) { //`people can not see which message came first, which is the last one` //`so can not know the message_interaction by reading code` switch (msg) { case MESSAGE_TIME_OUT: .... case MESSAGE_RESPONSE: .... case MESSAGE_XXXX: .... case MESSAGE_YYYY: .... } } }; ///////////////////////////////////////////////////////////////////////////// struct WorkerAfterRefactor : Worker { void operator()() { sender------->receiver(MessageBody); if_on_msg(sender<------------receiver(MESSAGE_TIME_OUT)) { sender------->receiver(MessageBody); if_on_msg(sender<------------receiver(MESSAGE_TIME_OUT)) { cout << "retry still got timeout..." << endl; } end_if_on_msg(MESSAGE_TIME_OUT); } end_if_on_msg(MESSAGE_TIME_OUT); if_on_msg(sender<-----receiver(MESSAGE_RESPONSE)) { cout << "succeeded got ack" << endl; } end_if_on_msg(MESSAGE_RESPONSE); } }; ///////////////////////////////////////////////////////////////////////////// int main(int argc, const char * argv[]) { WorkerAfterRefactor a; g_handlePool.addMsg(MESSAGE_SEND, a); g_handlePool.run(MESSAGE_SEND); g_handlePool.run(MESSAGE_TIME_OUT); g_handlePool.run(MESSAGE_TIME_OUT); g_handlePool.run(MESSAGE_RESPONSE); return 0; } ///////////////////////////////////////////////////////////////////////////// //output: //------>send sca config to slave board //<----timeout... //----->retry send sca config to slave board //<-----retry still got timeout... //<----succeeded got ack // //Process finished with exit code 0
2013-11-01
Make message interaction more readable, by using c++ local class
2013-10-25
USING operator overload to make your C++ functional test more readable
* usually we need test message communication between sub-systems, so the ft maybe looks like following: before refactor::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: struct HeartBeatAckTest : testing::Test { protected: SubSystemA aaa; SubSystemB bbb; Request request; }; TEST_F(HeartBeatAckTest, should_able_to_reply_heart_beat_ack) { MOCKER(shouldReceiveMsg) //using mockcpp .expects(exactly(1)) .with( eq(MSG_HEART_BEAT_ACK) , any() , eq(bbb.address()) , eq(aaa.address())); Msg::send(aaa, bbb, MSG_HEART_BEAT, &request); } //By using operator overload we can make send and receive more easy to read //we can set MOCKER by operator<, --, () and send msg by operator>, --, () after refactor::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: #define expects_msg if(true) TEST_F(AckTest, aaa_should_able_to_reply_heart_beat_ack) { expects_msg { aaa<-----bbb(MSG_HEART_BEAT_ACK); } aaa---->bbb(MSG_HEART_BEAT, &request); } TEST_F(AckTest, bbb_should_reply_heart_beat_ack___AND___forward_heart_beat_to_ccc) { expects_msg { aaa<-----bbb(MSG_HEART_BEAT_ACK); ccc<-----bbb(MSG_HEART_BEAT); } aaa---->bbb(MSG_HEART_BEAT, &request); } more thoughts:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: // the <----- is used to set MOCKER before ----->, can we? put the <---- after -----> , // to make the message interaction more easy to comprehensive. // similar to `RAII`, actually we can defer the send message operation of -----> to the end of scope expects_msg. struct SendAllBufferedMessageAtEndOfScope { SendAllBufferedMessageAtEndOfScope(int i) { } //make it can init from dummy int ~SendAllBufferedMessageAtEndOfScope() { send_all_buffered_message_in_sequence(); } operator bool() { return true; } }; #define expects_msg_interaction if (SendAllBufferedMessageAtEndOfScope sendMsgAtEnd = 1) TEST_F(AckTest, should_able_to_reply_heart_beat_ack) { expects_msg_interaction { aaa ----> bbb (MSG_HEART_BEAT, &request); //buffer the messge aaa <---- bbb (MSG_HEART_BEAT_ACK); //set the MOCKER specification //invisible destructor code of sendMsgAtEnd } } TEST_F(AckTest, bbb_should_reply_heart_beat_ack___AND___forward_heart_beat_to_ccc) { expects_msg_interaction { aaa ----> bbb (MSG_HEART_BEAT, &request); aaa <---- bbb (MSG_HEART_BEAT_ACK); ccc <---- bbb (MSG_HEART_BEAT); } } example code:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: struct SubSystemB { SubSystemB& operator--(int) { return *this; } template<typename T> bool operator >(const T& target) { target.receiveMsg(); return true; } }; struct SubSystemA { const SubSystemA& operator()(int msgId, int* p) { msgId_ = msgId; return *this; } void receiveMsg() const { std::cout << "cc got message: " << msgId_ << std::endl; } int msgId_; }; int main(int argc, const char * argv[]) { SubSystemB bbb; SubSystemA aaa; int param = 0; bbb---->aaa(1, ¶m); return 0; } //another example: TEST_F(AckTest, bbb_should_reply_heart_beat_ack___AND___forward_heart_beat_to_ccc) { expects_msg_interaction( op1 ----------------> xx (MSG_HEART_BEAT, &request); op1 <---------------- xx (MSG_HEART_BEAT_ACK); op2 ------------> xx (MSG_HEART_BEAT, &request); op3 --------> xx (MSG_HEART_BEAT, &request); op3 <-------- xx (MSG_HEART_BEAT_ACK); op4 ----> xx (MSG_HEART_BEAT, &request); op4 <---- xx (MSG_HEART_BEAT_ACK); op1 ----------------> xx (MSG_HEART_BEAT, &request); op1 <---------------- xx (MSG_HEART_BEAT_ACK); op2 ------------> xx (MSG_HEART_BEAT, &request); op3 --------> xx (MSG_HEART_BEAT, &request); op3 <-------- xx (MSG_HEART_BEAT_ACK); op4 ----> xx (MSG_HEART_BEAT, &request); op4 <---- xx (MSG_HEART_BEAT_ACK); ); }
2013-06-19
using emacs to manage temporary files during debugging
We always need some temporary files to do editing work. for example, we got 10000+ line logs to trace bug in it, first thing to do is create a tmp file. 1. To create a tmp file we'd like to - quick open the files in a directory without naming collision, with short-key `C-; t` - store the tmp files for future search/grep ;;code (defun create-and-open-tmp-file () (interactive) (find-file (s-concat "~/Documents/hongmin.wang/Google Drive/notes/tmp" (format-time-string "%Y%m%d___%H_%M_%S") (uuid-string) ".temp"))) (global-set-key (kbd "C-; t") 'create-and-open-tmp-file) 2. To manage versions of tmp file, we like to put it in a git direcotry and `C-x v i` to register the tmp file to git and `C-x v v` to commit new version of the tmp file to git. 3. sometime, you think the tmp file is no longer an tmp file, do a "Save As..." by `C-x C-w`
2013-06-09
2013-06-06
record and mock http interactions of third-party server
* Can not setup env in home. so i can not debug my application at home remotely I am debugging and web application, but I need an ESP fast server to always return XML data for my search, then I can debug things. but i can not access the fast server at home, so i can not work remotely at home. I want have an application to monitor my web application's interactions with fast server, and recording the interacting data(including delays), and can replay/mock the services at home. * python -m SimpleHTTPServer 9000 * http://localhost:9000/null_main.c * sudo justniffer -i lo0 -r -p "port 9000" GET /null_main.c HTTP/1.1 Host: localhost:9000 Connection: keep-alive Cache-Control: max-age=0 Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8 User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_7_4) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/27.0.1453.110 Safari/537.36 Accept-Encoding: gzip,deflate,sdch Accept-Language: en-US,en;q=0.8 If-Modified-Since: Sat, 20 Oct 2012 09:17:23 GMT HTTP/1.0 200 OK Server: SimpleHTTP/0.6 Python/2.7.1 Date: Thu, 06 Jun 2013 13:27:41 GMT Content-type: text/plain Content-Length: 46 Last-Modified: Sat, 20 Oct 2012 09:17:23 GMT /* null_main.c */ int main() { return 0; } * TODO need running the mock server according the recorded http data
-->
2013-05-11
2013-04-20
daily debugging tips and toolbox
* debugging tips strace:: http://www.thegeekstuff.com/2011/11/strace-examples/ where is the log files of specified process (e.g. nginx)? @firstly, find your process's pid ubuntu@ip:~ $ ps -ef | grep nginx root 13622 1 0 Mar03 ? 00:00:00 nginx: master process /usr/sbin/nginx www-data 13623 13622 0 Mar03 ? 00:03:19 nginx: worker process www-data 13624 13622 0 Mar03 ? 00:00:00 nginx: worker process www-data 13625 13622 0 Mar03 ? 00:03:19 nginx: worker process www-data 13626 13622 0 Mar03 ? 00:03:19 nginx: worker process ubuntu 19058 18961 0 10:31 pts/0 00:00:00 grep --color=auto nginx @secondly, using lsof to find all handle of that "pid", then grep it ubuntu@ip:~ $ sudo lsof -f -p 13622 | grep log nginx 13622 root 2w REG 202,1 0 145222 /var/log/nginx/error.log nginx 13622 root 5w REG 202,1 0 135398 /var/log/nginx/access.log nginx 13622 root 6w REG 202,1 0 145222 /var/log/nginx/error.log which process is listen on port 80? ubuntu@ip:~ $ sudo lsof -i:80 COMMAND PID USER FD TYPE DEVICE SIZE/OFF NODE NAME nginx 13622 root 7u IPv4 27232 0t0 TCP *:http (LISTEN) nginx 13623 www-data 7u IPv4 27232 0t0 TCP *:http (LISTEN) nginx 13624 www-data 7u IPv4 27232 0t0 TCP *:http (LISTEN) nginx 13625 www-data 7u IPv4 27232 0t0 TCP *:http (LISTEN) nginx 13626 www-data 7u IPv4 27232 0t0 TCP *:http (LISTEN) what's my process's environemnt variables? [vagrant@vagrant-centos-6-64 ~] $ ps -ef | grep apache apache 2136 1382 0 10:11 ? 00:00:00 /usr/sbin/httpd [vagrant@vagrant-centos-6-64 ~] $ sudo cat /proc/1382/environ TERM=linuxPATH=/sbin:/usr/sbin:/bin:/usr/binrunlevel=3RUNLEVEL=3LANGSH_SOURCED=1PWD=/LANG=Cprevious=NPREVLEVEL=NCONSOLETYPE=vtSHLVL=3UPSTART_INSTANCE=UPSTART_EVENTS=runlevelUPSTART_JOB=rc_=/usr/sbin/httpd let mysql log the queries? @execute following command in mysql console SET GLOBAL log_output = 'FILE'; Set GLOBAL general_log_file = '/tmp/mysql.log'; SET GLOBAL general_log = 'ON'; @ or directly in bash $ mysql -uroot -pYOUR-PASSWORD -e "SET GLOBAL log_output = 'FILE'; Set GLOBAL general_log_file = '/tmp/mysql.log'; SET GLOBAL general_log = 'ON';" @ then tail /tmp/mysql.log, see the quries against mysql $ tail -f /tmp/mysql.log how to monitor http request/response of this machine? @install justniffer on mac $ brew install boost $ brew install justniffer @ Capture all tcp traffic $ sudo justniffer -i eth0 -r GET /null_main.c HTTP/1.1 Host: localhost:9000 Connection: keep-alive Cache-Control: max-age=0 Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8 User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_7_4) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/27.0.1453.110 Safari/537.36 Accept-Encoding: gzip,deflate,sdch Accept-Language: en-US,en;q=0.8 If-Modified-Since: Sat, 20 Oct 2012 09:17:23 GMT HTTP/1.0 200 OK Server: SimpleHTTP/0.6 Python/2.7.1 Date: Thu, 06 Jun 2013 13:27:41 GMT Content-type: text/plain Content-Length: 46 Last-Modified: Sat, 20 Oct 2012 09:17:23 GMT /* null_main.c */ int main() { return 0; } @ Capture only http traffic $ sudo justniffer -i eth0 -r -p "port 80 or port 8080" @Capture smtp traffic (usually using tcp port 25) $ sudo justniffer -i eth0 -r -p "port 25" 220 plecno.com ESMTP Postfix (Ubuntu) EHLO unknown.localnet 250-plecno.com 250-PIPELINING 250-SIZE 250-VRFY 250-ETRN 250-STARTTLS 250-ENHANCEDSTATUSCODES 250-8BITMIME 250 DSN ... --Boundary-00=_ZI47J3FTNXn+25g Content-Type: text/html; charset="us-ascii" Content-Transfer-Encoding: 7bit <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd"> <html> <head> ... How to monitor changes in directory? @run following command, and try to touch/rm files. the results of `watch` will changing. $ watch -d -n 0.1 "ls" How to start a HTTP server on port 3000 for files in directory ~? $ cd ~ $ python -m SimpleHTTPServer 3000 TO BE CONTINUE::::
2013-04-08
2013-04-06
express-IOC
https://github.com/whunmr/express-ioc
https://github.com/johnelf/express-mvc
https://github.com/whunmr/express-orm
cglib introduction:
https://github.com/johnelf/express-mvc
https://github.com/whunmr/express-orm
Framework design:
- less intrusiveness
- simple to use
- Flent API: User.find_all().includes(Article.class);
- Convention over configuration
DEMO CODE
git@github.com:whunmr/express-orm.git
IMPLEMENTATION of Lazy List
- allOf
- anyOf
- both
- either
- describedAs
- everyItem
- is
- anything
- hasItem
- hasItems
- equalTo
- instanceOf
- any
- not
- nullValue
- notNullValue
- sameInstance
- containsString
- endsWith
- startsWith
- hasProperty
- samePropertyValuesAs
- array
- hasItemInArray
- arrayContainingInAnyOrder
- arrayContaining
- arrayWithSize
- emptyArray
- hasSize
- empty
- emptyIterable
- isIn
- isOneOf
- containsInAnyOrder
- contains
- iterableWithSize
- hasEntry
- hasKey
- hasValue
- closeTo
- comparesEqualTo
- greaterThan
- greaterThanOrEqualTo
- lessThan
- lessThanOrEqualTo
- hasToString
- typeCompatibleWith
- eventFrom
- isEmptyString
- isEmptyOrNullString
- equalToIgnoringCase
- equalToIgnoringWhiteSpace
- stringContainsInOrder
- hasXPath
- matcher1
- matcher2
- matcher3
- firstMethod
- secondMethod
- notStatic
- notPublic
- goodMethod
- anotherGoodMethod
- wrongReturnType
- generifiedType
- noGenerifiedType
- crazyType
- withParam
- withArray
- withVarArgs
- withGenerifiedParam
- withExceptions
- documented
- subclassMethod
GUAVA
moco:
dynamic-proxy:
git@github.com:whunmr/java-demos.git
intelliJ IDEA
foreach:
- iter (for each..in)
- itin (for..in)
- itli Iterate List itar Iterate array
- ritar reverse order
WORKSHOP about dynamic-proxy/cglib/javassist
a. how to using instrument lib
gradle clean idea
- in instrument folder, execute
gradle jar
- setup configuration so we can using the instrument agent jar, when running junit test. In IntelliJ IDEA, Run-->Edit Configurations…-->Defaults-->JUnit: set "VM Options:" to -javaagent:./instrument/build/libs/instrument.jar
c. find //TASK1 //TASK2 //TASK3, and finish the //TODOs in the task.
FUTHER READING:
Inside the Java Virtual Machine
2013-03-24
2013-01-20
Intellij IDEA plugin "emacsIDEAs" introduction
This is introduction to plugin emacsIDEAs of Intellij IDEA.
1) normal jump demo C-L <char>
2) jump to line end C-L <space>
type space to show line end.
3) Jump and Copy C-L <char> c <marker_char>
after markers show up, type 'c' to copy jump area.
4) Jump and Paste C-L <char> p <marker_char>
after markers show up, type 'p' to paste clipboard contents to jump target position.
5) Jump and Cut C-L <char> x <marker_char>
after markers show up, type x before marker_char to cut jump area.
6)Jump and Selection Cmd-L <char> s <marker_char>
7) during jump, type ESC to exit.
Installation:
Preferences... --> Plugins --> Browse repositories -> search "emacsIDEAs" to install
https://github.com/whunmr/emacsIDEAs
http://plugins.intellij.net/plugin?pr=idea&pluginId=7163
-->
2013-01-18
AceJump for Intellij IDEA development notes
** DONE C-I C-R (w | s | l | q | a | A | e | E | p | u | d) 't' 'm' : copy current word/line/paragraph, jump, then replace target word/line/paragraph ** TODO remove space chars (let only one space?)... ** TODO join selected lines ** TODO C-c n <char> to copy until ** TODO add a function like Cmd+Space to left only one space after caret ** TODO let C+, and C+. search exactly for currently selected string ** TODO add Cmd+c to zip copy char to ' ' ** TODO access left project file panel to jump ** DONE rename to emacsIDEAs ** DONE remove KeyEventDispatcher ** DONE remove unused comment ** DONE ESC to dismiss markers panel ** DONE bug: when show markers in one file, switch to another file can not jump again. ** DONE supports punctuation chars, such as !@#$%^&*()_-=+ ** DONE support max larger than 26 points to jump ** DONE test C-l ' ' will show markers of ' ' '\t' ** DONE test C-l '/' will show markers of line end. ** DONE jump to end of line ** DONE direct jump to location when only one jump candicate... ** DONE fix bug: when has horizental scroll ** DONE fix bug: when a-z as marker char set, typing 'A' should find 'a' ** DONE acejump selection mode ** DONE communicate system in intellij ** DONE jump to begin ** DONE acejump line mode ** DONE use different marker color for multiple jump markers ** DONE using C-l C-c for copy, and C-l C-x for cut, and C-l C-s for select ** TODO add C-c f to copy file name, C-c F to copy fullpath filename ** DONE add visiual effect after jump Copy ** DONE move to nearest intention area ** DONE C-c e copy to end ** DONE C-c b copy block ** DONE C-c ' ' A to cut to file beginning ** DONE C-c ' ' E to cut to file end ** TODO C-c P to copy paragraph but not copy trailling } ** TODO C-c E copy to end, but remove trialling unbalanced parenthesis ** DONE C-c ' ' p to cut paragraph ** DONE C-c ' ' ' ' p to select paragraph ** DONE C-c Q to copy quoted string with parenthesis ** TODO NOT_FOUND replace -1 ** DONE move focus to editor window when focus on some other window when type C-L ** DONE acejump word mode ** TODO add turn on and turn off function ** DONE show visual bell when error, such as not such key in document, no such marker char. ** DONE selection by execute two aceJump ** TODO replace char in line A->B... ** TODO shrink less used member variables ... ** TODO redraw panel when editor window resized. ** DONE copy word, paragraph, in "a" ** DONE add visiual effect after copy-without-selection. ** TODO create markers for left project navigation panel ** DONE show intention after move to quickfix intention... ** TODO replace true and false in key listener handler to boolean constant ** TODO cut to next char location ** TODO Anything in intellij ** DONE support word jump mode ** TODO support line jump mode ** TODO C-c f copy file name, C-c F copy file path name, C-c c copy class name, C-c C copy full class name
-->
Subscribe to:
Posts (Atom)