aboutsummaryrefslogtreecommitdiff
path: root/src/bun.js/module_loader.zig
diff options
context:
space:
mode:
authorGravatar Jarred Sumner <709451+Jarred-Sumner@users.noreply.github.com> 2022-11-07 19:50:28 -0800
committerGravatar Jarred Sumner <709451+Jarred-Sumner@users.noreply.github.com> 2022-11-07 19:50:54 -0800
commit41c983b3868a32257873795dd6248c91d87b27fe (patch)
treedbfb423c57402a5987767c67d03183bee8fc9fde /src/bun.js/module_loader.zig
parentf84b2ec6d122d811d7466050bdba0295a9c548d6 (diff)
downloadbun-41c983b3868a32257873795dd6248c91d87b27fe.tar.gz
bun-41c983b3868a32257873795dd6248c91d87b27fe.tar.zst
bun-41c983b3868a32257873795dd6248c91d87b27fe.zip
clean up some reliability issues with automatic install
Diffstat (limited to 'src/bun.js/module_loader.zig')
-rw-r--r--src/bun.js/module_loader.zig38
1 files changed, 31 insertions, 7 deletions
diff --git a/src/bun.js/module_loader.zig b/src/bun.js/module_loader.zig
index bee5fa1a1..ae415b65b 100644
--- a/src/bun.js/module_loader.zig
+++ b/src/bun.js/module_loader.zig
@@ -188,6 +188,7 @@ pub const ModuleLoader = struct {
// This is the specific state for making it async
poll_ref: JSC.PollRef = .{},
+ any_task: JSC.AnyTask = undefined,
pub const Id = u32;
const debug = Output.scoped(.ModuleLoader, false);
@@ -208,6 +209,7 @@ pub const ModuleLoader = struct {
pub const Queue = struct {
map: Map = .{},
+ scheduled: u32 = 0,
concurrent_task_count: std.atomic.Atomic(u32) = std.atomic.Atomic(u32).init(0),
const DeferredDependencyError = struct {
@@ -273,9 +275,11 @@ pub const ModuleLoader = struct {
var pm = this.vm().packageManager();
this.runTasks();
+ _ = pm.scheduleNetworkTasks();
+ this.runTasks();
+
this.pollModules();
_ = pm.flushDependencyQueue();
- _ = pm.scheduleNetworkTasks();
}
pub fn runTasks(this: *Queue) void {
@@ -414,8 +418,11 @@ pub const ModuleLoader = struct {
pub fn pollModules(this: *Queue) void {
var pm = this.vm().packageManager();
- var modules = this.map.items;
+ if (pm.pending_tasks > 0) return;
+
+ var modules: []AsyncModule = this.map.items;
var i: usize = 0;
+
for (modules) |mod| {
var module = mod;
var tags = module.parse_result.pending_imports.items(.tag);
@@ -459,8 +466,14 @@ pub const ModuleLoader = struct {
switch (pm.determinePreinstallState(package, pm.lockfile)) {
.done => {
- done_count += 1;
- tags[tag_i] = .done;
+ // we are only truly done if all the dependencies are done.
+ const current_tasks = pm.total_tasks;
+ // so if enqueuing all the dependencies produces no new tasks, we are done.
+ pm.enqueueDependencyList(package.dependencies, false);
+ if (current_tasks == pm.total_tasks) {
+ tags[tag_i] = .done;
+ done_count += 1;
+ }
},
.extracting => {
// we are extracting the package
@@ -473,9 +486,6 @@ pub const ModuleLoader = struct {
}
if (done_count == tags.len) {
- if (i + 1 >= modules.len) {
- this.vm().packageManager().endProgressBar();
- }
module.done(this.vm());
} else {
modules[i] = module;
@@ -529,6 +539,19 @@ pub const ModuleLoader = struct {
}
pub fn done(this: *AsyncModule, jsc_vm: *JSC.VirtualMachine) void {
+ var clone = jsc_vm.allocator.create(AsyncModule) catch unreachable;
+ clone.* = this.*;
+ jsc_vm.modules.scheduled += 1;
+ clone.any_task = JSC.AnyTask.New(AsyncModule, onDone).init(clone);
+ jsc_vm.enqueueTask(JSC.Task.init(&clone.any_task));
+ }
+
+ pub fn onDone(this: *AsyncModule) void {
+ var jsc_vm = this.globalThis.bunVM();
+ jsc_vm.modules.scheduled -= 1;
+ if (jsc_vm.modules.scheduled == 0) {
+ jsc_vm.packageManager().endProgressBar();
+ }
var log = logger.Log.init(jsc_vm.allocator);
defer log.deinit();
var errorable: ErrorableResolvedSource = undefined;
@@ -556,6 +579,7 @@ pub const ModuleLoader = struct {
&ref,
);
this.deinit();
+ jsc_vm.allocator.destroy(this);
}
pub fn resolveError(this: *AsyncModule, vm: *JSC.VirtualMachine, import_record_id: u32, result: PackageResolveError) !void {