- LSPMessageValidator: JSON-RPC 2.0 shape validation (method, id type, params type) - LSPCapabilityNegotiator: per-source capability tracking; shouldRoute gates on declared caps - LSPRequestThrottler: per-URI/method debounce; blocks rapid didChange floods - LSPErrorRecovery: per-source health tracking; stale-cache fallback when crashed - Sprint278IntegrationSummary: poly-parse (C++ + Haskell) end-to-end integration 26/26 tests passing (5+5+5+5+6). All new headers well under 600 lines. LoRA recorded: sprint278-2026-03-01 (9 calls, 6437 tokens). Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
65 lines
1.8 KiB
C++
65 lines
1.8 KiB
C++
#pragma once
|
|
#include "LSPDiagnosticsAggregator.h"
|
|
#include <map>
|
|
#include <set>
|
|
#include <string>
|
|
#include <utility>
|
|
#include <vector>
|
|
|
|
namespace whetstone {
|
|
|
|
class LSPErrorRecovery {
|
|
public:
|
|
void markCrashed(const std::string& source) {
|
|
crashed_.insert(source);
|
|
}
|
|
|
|
void markRecovered(const std::string& source) {
|
|
crashed_.erase(source);
|
|
}
|
|
|
|
// Unknown sources are healthy (optimistic default).
|
|
bool isHealthy(const std::string& source) const {
|
|
return crashed_.count(source) == 0;
|
|
}
|
|
|
|
std::vector<std::string> healthySources(
|
|
const std::vector<std::string>& all) const {
|
|
std::vector<std::string> result;
|
|
for (const auto& s : all)
|
|
if (isHealthy(s)) result.push_back(s);
|
|
return result;
|
|
}
|
|
|
|
void cacheDiagnostics(const std::string& source, const std::string& uri,
|
|
const std::vector<Diagnostic>& diags) {
|
|
cache_[{source, uri}] = diags;
|
|
}
|
|
|
|
// Returns cached diags if source is crashed, else empty.
|
|
std::vector<Diagnostic> fallbackDiagnostics(const std::string& source,
|
|
const std::string& uri) const {
|
|
if (isHealthy(source)) return {};
|
|
auto it = cache_.find({source, uri});
|
|
if (it == cache_.end()) return {};
|
|
return it->second;
|
|
}
|
|
|
|
void clearCache(const std::string& source) {
|
|
for (auto it = cache_.begin(); it != cache_.end(); ) {
|
|
if (it->first.first == source) it = cache_.erase(it);
|
|
else ++it;
|
|
}
|
|
}
|
|
|
|
int crashedCount() const {
|
|
return static_cast<int>(crashed_.size());
|
|
}
|
|
|
|
private:
|
|
std::set<std::string> crashed_;
|
|
std::map<std::pair<std::string, std::string>, std::vector<Diagnostic>> cache_;
|
|
};
|
|
|
|
} // namespace whetstone
|