Lesson 33-Node.js Source Code Architecture

Node.js Core Module Source Code

Event Loop Source Code Implementation

Node.js Event Loop Source Code Structure:

// src/node_main.cc
int main(int argc, char** argv) {
  // Initialize Node.js environment
  NodeMainInstance main_instance(...);
  // Enter event loop
  return main_instance.Run();
}

// src/node.cc
int NodeMainInstance::Run() {
  // Initialize libuv event loop
  uv_loop_t* loop = uv_default_loop();

  // Execute initialization callbacks
  Initialize(...);

  // Enter event loop
  uv_run(loop, UV_RUN_DEFAULT);

  // Clean up resources
  Cleanup();
  return 0;
}

Event Loop Phases Source Code:

// src/node.cc
void NodeMainInstance::Run() {
  // ...
  while (uv_run(uv_default_loop(), UV_RUN_ONCE) != 0) {
    // Process event loop phases
    ProcessTimers();          // Timers phase
    ProcessPendingCallbacks(); // Pending Callbacks phase
    ProcessIdleCallbacks();    // Idle/Prepare phase
    ProcessPollEvents();       // Poll phase
    ProcessCheckCallbacks();   // Check phase
    ProcessCloseCallbacks();   // Close Callbacks phase
  }
  // ...
}

Timer Implementation:

// src/timer_wrap.cc
void TimerWrap::Start(const FunctionCallbackInfo<Value>& args) {
  // Set timer callback
  uv_timer_start(timer_, OnTimeout, timeout, repeat);
}

void TimerWrap::OnTimeout(uv_timer_t* handle) {
  // Call JavaScript callback
  TimerWrap* wrap = static_cast<TimerWrap*>(handle->data);
  wrap->MakeCallback(env()->ontimeout_function());
}

Asynchronous I/O Source Code Implementation

libuv Call Flow:

// src/fs.cc
void FileSystem::ReadFile(const FunctionCallbackInfo<Value>& args) {
  // Create UV request
  uv_fs_t* req = new uv_fs_t;
  req->data = args.GetIsolate();

  // Call libuv async file read
  uv_fs_read(uv_default_loop(), req, fd, &buf, 1, offset, OnReadComplete);
}

void FileSystem::OnReadComplete(uv_fs_t* req) {
  // Process read result
  if (req->result < 0) {
    // Error handling
  } else {
    // Success handling
  }

  // Clean up resources
  delete req;
}

Thread Pool Integration:

// src/threadpool.cc
void ThreadPool::Initialize() {
  // Initialize libuv thread pool
  uv_threadpool_size(4); // Default 4 threads

  // Register work queue
  uv_queue_work(uv_default_loop(), &work_req, OnWork, OnAfterWork);
}

void ThreadPool::OnWork(uv_work_t* req) {
  // Execute task in worker thread
  WorkRequest* work = static_cast<WorkRequest*>(req->data);
  work->Execute();
}

void ThreadPool::OnAfterWork(uv_work_t* req, int status) {
  // Execute callback in event loop thread
  WorkRequest* work = static_cast<WorkRequest*>(req->data);
  work->Callback(status);

  // Clean up resources
  delete work;
  delete req;
}

File System (fs Module) Source Code Analysis

File Read Process:

// src/fs.cc
void FileSystem::ReadFile(const FunctionCallbackInfo<Value>& args) {
  // 1. Parameter validation
  if (args.Length() < 1 || !args[0]->IsString()) {
    return ThrowError("Invalid arguments");
  }

  // 2. Get file path
  String::Utf8Value path(args.GetIsolate(), args[0]);

  // 3. Open file
  uv_fs_t open_req;
  int fd = uv_fs_open(uv_default_loop(), &open_req, *path, O_RDONLY, 0, nullptr);

  // 4. Read file content
  uv_fs_t read_req;
  char buf[1024];
  uv_fs_read(uv_default_loop(), &read_req, fd, &buf, 1, 0, OnReadComplete);
}

void FileSystem::OnReadComplete(uv_fs_t* req) {
  // Process read result
  if (req->result < 0) {
    // Error handling
  } else {
    // Success handling
    Local<Value> result = String::NewFromUtf8(isolate, buf).ToLocalChecked();
    args.GetReturnValue().Set(result);
  }

  // Clean up resources
  delete req;
}

File System Cache Mechanism:

// src/fs.cc
class FileSystemCache {
 public:
  static FileSystemCache* GetInstance() {
    static FileSystemCache instance;
    return &instance;
  }

  void CacheFile(const std::string& path, const std::string& content) {
    std::lock_guard<std::mutex> lock(mutex_);
    cache_[path] = content;
  }

  bool GetCachedFile(const std::string& path, std::string* content) {
    std::lock_guard<std::mutex> lock(mutex_);
    auto it = cache_.find(path);
    if (it != cache_.end()) {
      *content = it->second;
      return true;
    }
    return false;
  }

 private:
  std::mutex mutex_;
  std::unordered_map<std::string, std::string> cache_;
};

Network Module (HTTP, TCP, UDP) Source Code Analysis

HTTP Server Implementation:

// src/http_server.cc
void HttpServer::Listen(const FunctionCallbackInfo<Value>& args) {
  // 1. Create UV TCP handle
  uv_tcp_t* server = new uv_tcp_t;
  uv_tcp_init(uv_default_loop(), server);

  // 2. Bind port
  sockaddr_in addr;
  uv_ip4_addr("0.0.0.0", 3000, &addr);
  uv_tcp_bind(server, (const struct sockaddr*)&addr, 0);

  // 3. Start listening
  uv_listen((uv_stream_t*)server, 128, OnConnection);
}

void HttpServer::OnConnection(uv_stream_t* server, int status) {
  if (status < 0) {
    // Error handling
    return;
  }

  // 1. Accept new connection
  uv_tcp_t* client = new uv_tcp_t;
  uv_tcp_init(uv_default_loop(), client);
  uv_accept(server, (uv_stream_t*)client);

  // 2. Create HTTP parser
  http_parser* parser = new http_parser;
  http_parser_init(parser, HTTP_REQUEST);

  // 3. Set data callback
  client->data = parser;
  uv_read_start((uv_stream_t*)client, OnAlloc, OnRead);
}

void HttpServer::OnRead(uv_stream_t* stream, ssize_t nread, const uv_buf_t* buf) {
  // Process HTTP request
  http_parser* parser = static_cast<http_parser*>(stream->data);
  size_t parsed = http_parser_execute(parser, &settings, buf->base, nread);

  if (parsed < nread) {
    // Parse error
    uv_close((uv_handle_t*)stream, OnClose);
  }
}

void HttpServer::OnClose(uv_handle_t* handle) {
  // Clean up resources
  delete static_cast<http_parser*>(handle->data);
  delete static_cast<uv_tcp_t*>(handle);
}

Module Loading Mechanism (require Source Code Flow)

Module Loading Process:

// src/module_wrap.cc
void ModuleWrap::Require(const FunctionCallbackInfo<Value>& args) {
  // 1. Get module path
  String::Utf8Value path(isolate, args[0]);

  // 2. Check cache
  Local<Object> cache = GetCache();
  Local<Value> cached_module = cache->Get(*path);
  if (!cached_module->IsUndefined()) {
    args.GetReturnValue().Set(cached_module);
    return;
  }

  // 3. Create new module
  Local<Object> module = Module::Create(isolate, *path);

  // 4. Compile module
  CompileModule(module, *path);

  // 5. Execute module
  ExecuteModule(module);

  // 6. Cache module
  cache->Set(*path, module);

  args.GetReturnValue().Set(module);
}

void ModuleWrap::CompileModule(Local<Object> module, const std::string& path) {
  // 1. Read file content
  std::string source = ReadFile(path);

  // 2. Create script
  Local<String> source_str = String::NewFromUtf8(isolate, source.c_str()).ToLocalChecked();
  Local<Script> script = Script::Compile(context(), source_str).ToLocalChecked();

  // 3. Set module exports
  module->SetInternalField(0, script);
}

void ModuleWrap::ExecuteModule(Local<Object> module) {
  // 1. Get script
  Local<Script> script = Local<Script>::Cast(module->GetInternalField(0));

  // 2. Execute script
  script->Run(context()).ToLocalChecked();

  // 3. Set module exports
  Local<Value> exports = module->GetInternalField(1);
  module->Set(context(), String::NewFromUtf8(isolate, "exports").ToLocalChecked(), exports).FromJust();
}

Membership Required

You must be a member to access this content.

View Membership Levels

Already a member? Log in here
Share your love