The purpose of the CompileController.js This controller is the application's "front desk." It has zero knowledge of how to compile LaTeX; its only job is to manage the request lifecycle, ensuring valid data goes in and valid JSON comes out.
Remember that in app.js we are calling many functions from CompileController.js for example, we had one operation where if a user clicks on the “compile button”, we were going to call the CompileController.compile function:
app.post(
'/project/:project_id/compile',
bodyParser.json({ limit: Settings.compileSizeLimit }), // Limit payload size
CompileController.compile // -> Goes to CompileController.js
)
so in this CompileController.js file, we are just defining all the functions that are called in the app.js , it’s like a handbook on how to use those functions, so this page is actually relatively very easy to understand, but compileController.js also calls a lot of functions from others as well, so we are going to discuss that as well.
sequenceDiagram
participant Client as Web Client
participant Ctrl as CompileController
participant Parser as RequestParser
participant Disk as PersistenceManager
participant Mgr as CompileManager
Client->>Ctrl: POST /project/:id/compile
Note right of Client: { compile: { options: {...}, resources: [...] } }
Ctrl->>Parser: parse(req.body)
activate Parser
Parser-->>Ctrl: cleanRequest (or Error)
deactivate Parser
alt Invalid Request
Ctrl-->>Client: 400 Bad Request
end
Ctrl->>Disk: markProjectAsJustAccessed(id)
Ctrl->>Mgr: doCompileWithLock(request)
activate Mgr
alt Locked (Another compile running)
Mgr-->>Ctrl: Error: AlreadyCompiling
Ctrl-->>Client: 423 Locked
else Success
Mgr->>Mgr: Run Docker Build...
Mgr-->>Ctrl: { buildId: "abc", outputFiles: [...] }
Ctrl->>Ctrl: Format Response URLS
Note right of Ctrl: url: /project/id/build/abc/output/output.pdf
Ctrl-->>Client: 200 OK { status: "success", outputFiles: [...] }
end
deactivate Mgr
app.js our app.js was like the director, he said that whenever the user clicks on the compile button, it would call a compile function from us, you can see this code is basically is exactly how the function compile would operate.//COMPILE FUNCTION
function compile(req, res, next) {
.....//source code.....
}
Now let’s dive into some details of how compile function in compileController.js file works.
req.body , so what is req.body? req is just a JavaScript object that represents the incoming HTTP request from a client to a server in a server-side environment like Express.js or Node.js. body is just the content. What the hell does this mean? —> Remember that right now we are still at the stage where we try to send our LaTeX codes to a server that knows how to compile it, to send something, we need to package it, and find a route to deliver our “mail”, so the way to do this is we encapsulate it in JSONJSON is the standard format for organizing data. Then via HTTP POST request (this code) we send it to the controllerCompiler.js where it’s compile function will do the work. In a more technical term:<aside>
The client serializes the document state (including LaTeX code and file metadata) into a JSON object and transmits it as the request body of a POST call."
</aside>
Back to what we were talking about, the function compile(req, res, next) {...} will parse the JSON payload first as shown in the following code:
RequestParser.parse(req.body, function (error, request) {
if (error) {
return next(error)
}
timer.opts = request.metricsOpts
request.project_id = req.params.project_id
if (req.params.user_id != null) {
request.user_id = req.params.user_id
}
CompileManager.doCompileWithLock(
request,
stats,
timings,
(error, result) => {
let { buildId, outputFiles } = result || {}
let code, status
if (outputFiles == null) {
outputFiles = []
}
if (error instanceof Errors.AlreadyCompilingError) {
code = 423 // Http 423 Locked
status = 'compile-in-progress'
} else if (error instanceof Errors.FilesOutOfSyncError) {
code = 409 // Http 409 Conflict
status = 'retry'
logger.warn(
{
projectId: request.project_id,
userId: request.user_id,
},
'files out of sync, please retry'
)
} else if (
...//SOME CODE THAT RETURNS ERROR, NOT SO IMPORTANT FOR THIS
...//GUIDED LEARNING
)
This part is the core because you can see now compileController.js is calling function from CompileManager and it is a function called doCompileWithLock So now that we know if we want to look at how the actual execution looks like we gotta navigate to CompileManager.js