SocketChannel의 read 메쏘드는 timeout이 존재하지 않습니다.
혹, SocketChannel 객체의 .socket() 메쏘드로  소켓객체의  타임아웃을 세팅해도 먹지 않죠.. ^^;;
그래서, non-blocking의 read 메쏘드에 대한 timeout은 busy waiting하는 형태로 타임아웃을 줄 수 있겠습니다..

                // 20초               
                long timeout = 20 * 1000;  
                long stime = new Date().getTime();
                long rtime = 0L;
               
                int rvalue =0;
                int rvalues = 0;
                while (rtime < timeout ) {
                    rtime = System.currentTimeMillis() - stime;
                    rvalue = channel.read(rbuffer);
                    if(rvalue == -1)
                        throw new Exception("connection closed");
                   
                    rvalues = rvalues + rvalue;
                    if(rtime > timeout)
                        throw new Exception("read timeout exception");

                    if(rvalues >= 4)
                        break;
                }

저작자 표시
non-blocking SocketChannel에서 끝까지 읽어오는 코드입니다.
개인적으로 헤더 8byte, 헤더의 앞의 4byte를 전체 패킷을 길이로 잡습니다.
그리고, 아래처럼 SocketChannel에서 packet handling variables와 같이 패킷을 끝까지 다 읽어 들입니다.
아래 내용은 non-block으로 대용량의 바이너리 데이타를 읽어들이기 위해서 꼭 필요한 내용일 듯 합니다.

* read() 내용

    //// packet handling variables
    private int fullsize = 0;
    private int readedsize =0;
    private int minsize = 8;
   
    @Override
    public void read() {       
        try {
            // 읽기
            int rbytes = this.channel.read(rbuffer);
                   
            // 연결종료
            if (rbytes == -1) {
                ((ChannelListener)this.listener).disconnected(this);
                this.close();
                return;
            }
   
            // 버퍼에 내용이 없는 경우
            if (rbytes == 0) {
                this.channel.configureBlocking(false);
                this.handle();
                return;
            }
           
            // 읽은 바이트 갯수를 증감시킨다.
            readedsize += rbytes;   
            rbufferList.add(this.copy(this.rbuffer, rbytes));
           
            // 최소 패킷의 길이에서 패킷을 전체 길이를 리턴한다.
            if(readedsize >= minsize && this.fullsize == 0) {
                this.fullsize = this.createResultBuffer().getInt();
                for(int i=0; i< this.rbufferList.size(); i++) {
                    this.rbufferList.get(i).position(0);
                }
            }
           
            // 패킷을 다 읽어 들였다.
            if(fullsize == readedsize) {
                ((ChannelListener)this.listener).arrived(this,this.createResultBuffer());
            }
           
            this.channel.configureBlocking(false);
            this.handle();
        } catch(Exception e) { // disconnected
            try {
                this.close();
            } catch(IOException ie) {
                new CallbackExceptionHandler().handle(ie);
            }
           
            ((ChannelListener)this.listener).disconnected(this);
        }
    }

저작자 표시
위와 같은 에러가 나올경우..
흠.. 알면 쉬운데.. 왜 나는지 정확하게 모르면 엄청 고생하게 되네요..

위 내용은 Mapper에 선언되어 있는 메쏘드 이름과 mapper 파일의 select나 insert등의 이름과 일치하지 않아서 발생합니다.. 아래 처럼 말이죠.. ^^;;

ex) 인터페이스 이름
public String print(String x) throws Exception;

ex) mapper.xml
<select id="prints" statementType="CALLABLE" parameterType="String" resultType="String">
        .........................
</select>


저작자 표시
Tag // iBATIS, Mapper, mybatis

Concurrent vs Parallel

from Lectures 2010/09/13 11:29
Concurrent와 Parallel의 개념에 대한 내용입니다..
전에 http://choiwonwoo2.tistory.com/ 님께서 concurrent와 parallel의 차이에 대해서 설명해 주신 내용이 알듯말듯.. 했는데, 아래의 링크의 내용을 보니 명확하게 눈에 들어오네요.. ^^

http://www.google.com/buzz/leedaeyeop/2NL6hyr45hL/Parallel-programming-in-NET-Introduction-http

위 링크를 따라 들어가면 나오는 내용입니다.

Concurrent applications tend to create a thread that handles a whole series of tasks. Most of the time these concurrent applications create threads because they need an isolated process for a concurrent event.
Parallel applications divide a process into small tasks that are executed on seperate threads. Because the tasks are small, the threads can be divided evenly over the processors, resulting in very efficient use of a multi-core CPU.

아래의 이미지는 concurrent와 parallel의 차이에 대한 좋은 예입니다.

저작자 표시

'Lectures' 카테고리의 다른 글

Concurrent vs Parallel  (0) 2010/09/13
OOD 설계 원칙들..  (0) 2010/08/31
NOSQL 정리  (0) 2010/07/06
CI(Continuous Integration)  (0) 2010/07/05
CAP Theorem  (0) 2010/06/16
흠...
현재 개발된 프레임웍의 구조는 master, slave reactor가 있고.. slave reactor가 네트웍 이벤트를 디스패칭을 하고있는 구조이고, 또 socketchannel의 read 메쏘드를 통해서 bytebuffer를 worker 쓰레드에 넘기는 구조인데요..

최근에 큰 사이즈의 이미지를 전송하다 보니....
worker 쓰레드에서 socketchannel의 read 메쏘드를 호출하는 것이 더 맞아보이기도 하고..

흠.. socketchannel의 read 메쏘드를 호출하는 객체가 slave reactor가 되야 될까요?? 아님 worker 쓰레드가 되야 될까요??

고민이네.. ㅜㅜ

저작자 표시

install lighttpd on ubuntu

from Os 2010/09/08 21:58
1. install
sudo apt-get install lighttpd

2. start/stop & restart
/etc/init.d/lighttpd start
/etc/init.d/lighttpd stop
/etc/init.d/lighttpd restart

3. config dir
/etc/lighttpd
저작자 표시
라이브러리..
 이넘 덕분에 프로그래밍이 많이 쉬워졌죠.. 특히, 자바진영에서는 Apache 재단의 지원이 매우 강력한 힘이 되고 있는게 현실이죠..
라이브러리를 사용하기 위해서는 의존하고 있는 라이브러리도 함께 있어야 제대로 동작을 하겠죠..
그리고, 라이브러리는 자신을 사용하는 클라이언트에게 에러 상황(Exception)에 대한 내용도 알려주겠죠?..

ㅎㅎ
위 상황을 가정하면, 왜 라이브러리가 로깅을 해야 될까요??
로깅이 debugging을 위한 거라고 가정을 한다면, 그 몫은 에러 상황을 리턴받은 클라이언트 몫이 아닐까요??

흠.. 정답이 없어서 모라 하긴 그렇지만..
개인적으로 라이브러리가 로깅을 하는것은 좋지 않다고 생각을 하는데..
혹시 저와 다른 생각이 있으신 분들은 답글 좀..  ^^
 



저작자 표시
우분투를 메인 OS로 사용하고 있는데, 가끔 윈도우도 필요하고, 클러스터링 구성하기 위해서 VirtualBox로 리눅스/윈도우를 사용하고 있는데.. USB 인식이 안되서 에이.. 하고 말았는데.. 매우 좋은 팁이네요..
자세한 내용은 http://simplism.kr/wordpress/?p=816 을 참고하세요..
저작자 표시