2013-11-01

Make message interaction more readable, by using c++ local class





main (1).cpp



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-10-25

USING operator overload to make your C++ functional test more readable





tricks-cpp-operator-for-sendmsg.org



* 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, &param);

    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





a.lisp



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-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-04-20

daily debugging tips and toolbox





debugging.org



* 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-06

express-IOC

https://github.com/whunmr/express-ioc
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:

cglib introduction:

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
  1. gradle clean idea
  2. in instrument folder, execute gradle jar
  3. 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


b. get the task from here https://github.com/whunmr/java-demos

c. find //TASK1 //TASK2 //TASK3, and finish the //TODOs in the task.


FUTHER READING:
Inside the Java Virtual Machine




2013-01-20

Intellij IDEA plugin "emacsIDEAs" introduction





tmp20130120___18_22_24035445a0-708d-6194-29cb-eaa258d94fed.temp

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





intellijmacs.org




** 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

-->