MCPcopy Create free account
hub / github.com/PHPantom-dev/phpantom_lsp / phpstan_worker

Method phpstan_worker

src/diagnostics/mod.rs:1112–1261  ·  view source on GitHub ↗

Long-lived background task that runs PHPStan on pending files. Spawned once during `initialized`, alongside the main diagnostic worker. This task is completely independent: native diagnostics (phases 1 and 2) are never blocked by PHPStan. ## Serialization guarantee At most one PHPStan process runs at a time. The worker loop: 1. Wait for a notification (new edit arrived). 2. Debounce: sleep [

(&self)

Source from the content-addressed store, hash-verified

1110 /// notification and loops back to step 1, starting a fresh run
1111 /// with the latest content.
1112 pub(crate) async fn phpstan_worker(&self) {
1113 loop {
1114 if self.shutdown_flag.load(Ordering::Acquire) {
1115 return;
1116 }
1117
1118 // ── Step 1: wait for work ───────────────────────────────
1119 self.phpstan_notify.notified().await;
1120
1121 if self.shutdown_flag.load(Ordering::Acquire) {
1122 return;
1123 }
1124
1125 // Drain any extra stored permits so that notifications
1126 // that arrived between the last run finishing and this
1127 // `notified()` call don't cause an immediate second run.
1128 // `Notify::notify_one()` stores at most one permit, but
1129 // multiple `schedule_phpstan` calls during debounce or
1130 // execution could leave one behind.
1131 //
1132 // We consume it by polling a fresh `notified()` with a
1133 // zero timeout — if there's a stored permit it resolves
1134 // immediately, otherwise it times out harmlessly.
1135 let _ = tokio::time::timeout(std::time::Duration::ZERO, self.phpstan_notify.notified())
1136 .await;
1137
1138 // ── Step 2: debounce (longer than normal diagnostics) ───
1139 loop {
1140 let version_before = self.diag_version.load(Ordering::Acquire);
1141 tokio::time::sleep(std::time::Duration::from_millis(PHPSTAN_DEBOUNCE_MS)).await;
1142 let version_after = self.diag_version.load(Ordering::Acquire);
1143 if version_before == version_after {
1144 break;
1145 }
1146 // More edits arrived — loop and debounce again.
1147 }
1148
1149 // ── Step 3: snapshot the pending URI ────────────────────
1150 let uri = {
1151 let mut pending = self.phpstan_pending_uri.lock();
1152 pending.take()
1153 };
1154 let uri = match uri {
1155 Some(u) => u,
1156 None => continue,
1157 };
1158
1159 // Snapshot the file content.
1160 let content = {
1161 let files = self.open_files.read();
1162 match files.get(&uri) {
1163 Some(c) => c.clone(),
1164 None => continue,
1165 }
1166 };
1167
1168 // ── Step 4: resolve PHPStan binary ──────────────────────
1169 let config = self.config();

Callers 1

initializedMethod · 0.80

Calls 13

read_composer_packageFunction · 0.85
get_bin_dirFunction · 0.85
resolve_phpstanFunction · 0.85
run_phpstanFunction · 0.85
cloneMethod · 0.80
configMethod · 0.80
is_disabledMethod · 0.80
assemble_and_pushMethod · 0.80
loadMethod · 0.45
takeMethod · 0.45
getMethod · 0.45
mapMethod · 0.45

Tested by

no test coverage detected