Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions ferus.nimble
Original file line number Diff line number Diff line change
Expand Up @@ -13,12 +13,12 @@ bin = @["ferus", "ferus_process"]
requires "nim >= 2.0.2"
requires "ferusgfx >= 1.2.1"
requires "colored_logger >= 0.1.0"
requires "stylus#master"
requires "stylus >= 0.1.3"
requires "https://github.com/ferus-web/sanchar >= 2.0.2"
requires "https://git.sr.ht/~bptato/chame >= 1.0.1"
requires "seccomp >= 0.2.1"
requires "simdutf >= 5.5.0"
requires "https://github.com/ferus-web/bali >= 0.6.3"
requires "https://github.com/ferus-web/bali#master"
requires "results >= 0.5.0"
requires "pretty >= 0.1.0"
requires "jsony >= 1.1.5"
Expand Down
2 changes: 1 addition & 1 deletion src/bindings/yoga.nim
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ static:
echo pwd

{.passC: "-I" & gorge("pwd") & "/install/include".}
{.passL: "-L" & gorge("pwd") & "/install/lib64 -lyogacore".}
{.passL: "-L" & gorge("pwd") & "/install/lib -lyogacore".}

{.push header: "<yoga/Yoga.h>".}
type
Expand Down
2 changes: 2 additions & 0 deletions src/components/ipc/shared.nim
Original file line number Diff line number Diff line change
Expand Up @@ -395,6 +395,8 @@ proc magicFromStr*(s: string): Option[FerusMagic] =
return some feJSTakeDocument
of "feRendererExit":
return some feRendererExit
of "feGoodbye":
return some feGoodbye
else:
warn "magicFromStr(" & s & "): no such magic string found."

Expand Down
11 changes: 10 additions & 1 deletion src/components/js/process.nim
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ type JSProcess* = object
ipc*: IPCClient
parser*: Parser
runtime*: Runtime
running*: bool = true

document*: HTMLDocument

Expand Down Expand Up @@ -72,6 +73,14 @@ proc talk(js: var JSProcess, process: FerusProcess) =

debug "Got document for this tab - passing it to JS land."
js.document = packet.document
of feGoodbye:
info "js: got goodbye packet, cleaning up."
# TODO: make it so that we always respond to goodbye(s), even when in an unreachable/expensive VM loop
# there's two ways to do this:
# a) either add a way for a hook function to constantly monitor for this packet (bad performance)
# b) shift the VM to another thread (good performance but harder to work with)
js.runtime.vm.halt = true
js.running = false
else:
discard

Expand All @@ -87,5 +96,5 @@ proc jsProcessLogic*(client: var IPCClient, process: FerusProcess) {.inline.} =
else:
setLogFilter(lvlNone)

while true:
while js.running:
js.talk(process)
20 changes: 19 additions & 1 deletion src/components/master/master.nim
Original file line number Diff line number Diff line change
@@ -1,3 +1,7 @@
## The IPC "master". This is just an abstraction over the IPC server.
## It essentially allows you to do anything with your own group of processes (renderer, JS runtime, CSS/HTML parsers, etc.)
## This includes summoning them, telling them to do a task, telling them to exit, et cetera.

import
std/
[os, logging, osproc, strutils, options, base64, net, sets, terminal, posix, tables]
Expand Down Expand Up @@ -25,6 +29,8 @@ type MasterProcess* = ref object
server*: IPCServer
urls*: Table[uint, URL]

alive*: bool = true

proc initialize*(master: MasterProcess) {.inline.} =
master.server.add(FerusGroup())
# TODO: multi-tab support, although we could just keep adding more FerusGroup(s) and it should *theoretically* scale
Expand Down Expand Up @@ -515,8 +521,20 @@ proc packetHandler*(
master.server.reportBadMessage(
process, "Non-renderer process sent `feRendererExit` opcode", High
)
return

info "The renderer has shut down. Beginning cleanup."

# Here, we start sending "goodbye" packets to all processes.
# We're essentially telling them, "Hey, start cleaning up and die."
for i, group in master.server.groups:
for process in group:
debug "Telling PID " & $process.pid & " (group " & $i & "'s " & $process.kind &
") to exit"
master.server.send(process.socket, GoodbyePacket())

debug "The renderer has shut down."
info "Cleanup completed. Adios!"
master.alive = false
else:
warn "Unhandled IPC protocol magic: " & $kind
return
Expand Down
13 changes: 12 additions & 1 deletion src/components/network/process.nim
Original file line number Diff line number Diff line change
Expand Up @@ -162,6 +162,17 @@ proc talk(client: FerusNetworkClient, process: FerusProcess) {.inline.} =
info "network: Created WebSocket connection to address " & $openReq.address &
" successfully!"
client.ipc.send(NetworkWebSocketCreationResult(error: none(string)))
of feGoodbye:
info "network: received goodbye packet."

info "network: closing all websockets"
for ws in client.websockets:
ws.handle.close()

info "network: closing cURL handle"
curl.close()

client.running = false
else:
discard

Expand All @@ -170,6 +181,6 @@ proc networkProcessLogic*(client: var IPCClient, process: FerusProcess) {.inline
var client = FerusNetworkClient(ipc: client)
client.ipc.setState(Idling)

while true:
while client.running:
client.talk(process)
client.tickAllConnections()
1 change: 1 addition & 0 deletions src/components/network/types.nim
Original file line number Diff line number Diff line change
Expand Up @@ -10,3 +10,4 @@ type
FerusNetworkClient* = ref object
ipc*: IPCClient
websockets*: seq[WebSocketConnection] ## All open WebSocket instances
running*: bool = true
20 changes: 17 additions & 3 deletions src/components/parsers/html/process.nim
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,13 @@ proc htmlParse*(oparsingData: Option[ParseHTMLPacket]): HTMLParseResult =

HTMLParseResult(document: some(document.parseHTMLDocument()))

proc talk(client: var IPCClient, process: FerusProcess) {.inline.} =
type HTMLParserData* = object
running*: bool = true
documentsParsed*: uint64

proc talk(
client: var IPCClient, state: var HTMLParserData, process: FerusProcess
) {.inline.} =
var count: cint
discard nix.ioctl(client.socket.getFd().cint, nix.FIONREAD, addr(count))

Expand Down Expand Up @@ -53,13 +59,21 @@ proc talk(client: var IPCClient, process: FerusProcess) {.inline.} =

client.send(data)
client.setState(Idling)

inc state.documentsParsed
of feGoodbye:
info "html: got goodbye packet, exiting."
info "html: we parsed " & $state.documentsParsed &
" documents throughout this process's lifetime"
state.running = false
else:
discard

proc htmlParserProcessLogic*(client: var IPCClient, process: FerusProcess) {.inline.} =
info "Entering HTML parser process logic."
var data = HTMLParserData()
client.setState(Idling)
client.poll()

while true:
client.talk(process)
while data.running:
client.talk(data, process)
2 changes: 1 addition & 1 deletion src/ferus.nim
Original file line number Diff line number Diff line change
Expand Up @@ -75,7 +75,7 @@ proc main() {.inline.} =
tab1.load()
tabs.add(tab1.move())

while true:
while tabs[0].master.alive:
master.poll()
for i, _ in tabs:
tabs[i].heartbeat()
Expand Down
Loading