v8 add on with middleware modules
DESCRIPTION
V8 Add onTRANSCRIPT
V8 Add-On With Middle-ware Modules
Code name Ib. js 데이터 솔루션 팀 Jay
INDEX
V8 소개 V8 Add-on 이란 V8 Add-on 을 위한 사전 지식 실전 테스트 Echo Server & Client
Let’s Discuss !
V8 소개
Well-Maden Java-script Engine Chrome 의 Java script 엔진으로 유명세를 타기 시작함 모두 C++ 코드로 짜여짐 Build 는 GYP 를 활용한 makefile 방식 타고난 성능으로 인해 다양한 open-source project 에 활용되고 있다 .
프로젝트 사이트 : https://code.google.com/p/v8/
특징 가비지 콜렉터 성능이 다른 엔진에 비해 매우 좋다 .
광범위한 캐싱의 활용 C++ 모듈의 추가나 다른 C++ 로 짜여진 application 에 이식이 용이 단 , 메모리의 점유가 많은 편
V8 Add-on 이란 ?
정의 ? ( 거창하네 ..) C++ 모듈을 추가하여 V8 의 Java-script 를 확장하는 방법
C++ 모듈을 추가하여 확장한 javascript 규격을 빌드한 v8 에서 활용하여 코딩이 가능하다 !
Node.js 역시 이러한 방법을 이용해 다양한 규격을 제공 .
기본적인 Add-on 방식 확장할 규격을 정하여 javascript 에 공개할 형식을 정한다 .
Object?
Function?
정해진 형식으로 Template 을 만든다 .
Template 을 통해 Instance 를 만들고 Javascript Heap 에 올려준다 .
V8 Add-on 을 위한 사전 지식
주요 클래스 정리 Isolate
V8 instance 를 생성하고 관리하는 클래스 .
Context
JavaScript 를 사용하기 위한 Context instance 를 생성하고 관리하는 클래스 HandleScope
GC 가 동작하는 기준이 되는 Scope 를 생성하는 클래스 . 이 클래스의 인스턴스가 생성되고 파괴되면 해당 범위에서 생성된 Handle 들은 모두 GC 의 대상이 된다 .
Handle
Heap 에 관리되는 객체를 생성하고 접근할 수 있게 해주는 클래스 Local - HandleScope 에 영향을 받는 handle 클래스 Persistant - HandleScope 에 영향을 받지 않는 handle 클래스
FunctionTemplate
Javascript 측에 Function 을 노출하기 위해 사용하는 클래스로 , 한 번 Function Template 만들어 두면 해당 객체를 통해 간단하게 Javascript 측에 노출할 Function 객체를 생성할 수 있다 .(ex: 여러개의 isolate 에 동일한 규격으로 함수를 노출할 때 )
ObjectTemplate
Javascript 측에 Object 를 노출하기 위해 사용하는 클래스로 , 한 번 Object Template 을 만들어 두면 해당 객체를 통해 간단하게 Javascript 측에 노출할 Object 의 객체를 생성 할 수 있다 .(ex: 특정 Function 을 new 를 통해 생성시키는 경우 Constructor 에서 사용 )
V8 Add-on 을 위한 사전 지식
V8 Add-on 을 위한 사전 지식
GYP (Generate your project) Json 문법을 이용해 프로젝트 파일을 만들어 주는 Opensource project
Makefile 뿐만 아니라 Xcode 와 VisualStudio 용 프로젝트 파일들도 생성 가능하다 !!
V8 프로젝트의 모든 makefile 이 gyp 를 통해 만들어짐 .
프로젝트 사이트 : https://code.google.com/p/gyp/
C++ 모듈을 추가할 때 해당 모듈들에 대한 gyp 파일을 생성하고 해당 gyp 파일을 v8 빌드에 include 시켜야 한다 .
Clean 룰은 별도로 만들어야 함 .(v8 add-on 작업시에는 v8 에서 만들어 둔 rule 을 사용하면 됨 )
실전 – ib.js 구상
어떤 모듈을 노출해 볼까 ? IChannel
멀티스레드를 기반으로 동작하는 네트워크 클래스 CSessionSock
IChannel 에서 사용하는 세션 클래스
모듈들을 어떻게 노출 할까 ? Function !!
Object ?
Function vs Object Win! 상속 처리 LoseWin! 메모리 사용 Lose
실전 – ib.js 살 붙이기
Namespace 를 쓰고 싶은데… net.ib.Channel
Net.ib.SessionSock
Function Template 만들기 Function 을 통해 클래스를 노출하고 , 각각의 Api 들은 Javascript 의 prototype 을 통해 노출되도록 하자
상속을 위해서
Javascript 로 부터 호출된 C++ 함수에서 리턴값 처리는 ?
void InsertAllModules(){ //make "net" object v8::Local<v8::FunctionTemplate> netFTempl = v8::FunctionTemplate::New(V8Isolate::get()); //make "ib" object v8::Local<v8::FunctionTemplate>ibFTempl= v8::FunctionTemplate::New(V8Isolate::get());
//set net into ib ibFTempl->Set(V8Isolate::get(),"net", netFTempl);
//BufferExtern::InstallStrBuffer(netFTempl, NULL); ChannelExtern::getInstance()->installClass(netFTempl, (char*)"Channel"); SessionSockExtern::getInstance()->installClass(netFTempl, (char*)"SessionSocket");
//create global obj template to set into global context v8::Local<v8::ObjectTemplate>global= V8Global::get(); //insert apiset object to global ObjectTemplate. global->Set(V8Isolate::get(), "ib", ibFTempl);}
voidIExternBase::installClass(v8::Local<v8::Template> target, char* name){
//make inner template & save itLocal<FunctionTemplate> tmpl =
FunctionTemplate::New(V8Isolate::get());
//install methods to templateinstallPrototypeFunctions(tmpl);if (_funcTemplate.IsEmpty()) _funcTemplate =
tmpl;
//make outer template & expose itLocal<FunctionTemplate> outerTempl =
FunctionTemplate::New(V8Isolate::get(), constructorCallback);installPrototypeFunctions(outerTempl);
//set to targetif (target.IsEmpty() == false)
target->Set(V8Isolate::get(), name, outerTempl);
}
void SessionSockExtern::PopFrontRecvBuf(const v8::FunctionCallbackInfo<v8::Value>& info){
CSessionSock* ptr= (CSessionSock*)Unwrap<CSessionSock>(info.Holder());
intres= ptr->PopFrontRecvBuf(info[0]->Int32Value());info.GetReturnValue().Set(res);
}
실전 – ib.js 살 붙이기
어라 ? IChannel 은 Interface 클래스다 .. 순수 가상 함수를 어쩐다…
악 ~! 생성자가 계속 호출된다 !!(recursive calling)
Thread safety 문제가… 스레드에서 javascript 함수 호출이 되지 않는다 !!
가상 함수를 구현한 자식 클래스를 만들어 해당 클래스를 노출하기로 결정
동일한 FunctionTemplate 을 2 개 만들어 외부 노출용과 객체 생성용으로 구분하여 생성자에서 호출하도록 수정
메인 스레드에 간단한 이벤트 루프를 구성하여 스레드에서 해당 이벤트 루프에
함수 호출을 위임
실전 – ib.js 완성 ?!
끝으로 main 함수에서 할 일이 뭘까 ?
빌드를 위한 gyp 설정하기
ibShell 완성 ~
• Context 생성• 확장 모듈 노출을 위한 install• 소스 스크립트 컴파일• 스크립트 실행
V8/build/all.gyp 파일 수정 { 'targets': [ { 'target_name': 'All', 'type': 'none', 'dependencies': [ '../samples/samples.gyp:*', '../src/d8.gyp:d8',#steady add line'../../middleware/V8Extern/build/ib.gyp:*'# '../test/cctest/cctest.gyp:*', ], 'conditions': [ ['component!="shared_library"', { 'dependencies': [ '../tools/lexer-shell.gyp:lexer-shell', '../tools/lexer-shell.gyp:parser-shell', ], }], ] } ]}
Test Echo Server&Client
ib.js 테스트 단순 Echoing Server 를 javascript 로 구현 Session 맺고 곧바로 8Byte 의 데이터를 송신하는 Client 를 javascript 로 구현
비교 테스트 동일한 로직의 C++ Echoing Server/client 작성하여 비교 테스트 수행 .
( 동일한 Middleware Module 들 사용하여 구현 )
Memory Usage Client(60,000 sessions set)
Server(500,000 sessions capa-ble)
Idle state 3,489,136 bytes 15,722,292 bytes
Running 2,933,420 bytes 11,381,124 bytes
60,000 Session & 60,000 Req. & Res.
Not changed Not changed
Speed Checking Ib.js C++
60,000 Sessions&60,000 Req. & Res. Avg. 9.6 Avg. 9.3
★ 서버 테스트 장비 : 172.16.0.162 (cpu: i5-3570 3.4 GHz, ram: 16GB)★ 클라이언트 테스트 장비 : 172.16.0.194(cpu: Q8300 2.5GHz(2.0) ram: 4GB)★ 최적화에 대한 고민 없이 한 테스트로 최적화 수행 후 결과는 차이가 있을 수 있음 .
Let’s Discuss !
V8 의 성능은 서버로 쓸 만 한가 ?
Node.js 의 성능은 ?
Java JNI : v8(Javascript) Add-on
앞으로 해봐야 할 것들은 ?