Migrate plugin channels to protomux-rpc only

Replace dual message-channel + RPC setup with a single registerPluginProtocol
path, unified sdk.channels (register/request/event/broadcast), RPC keepalive
(__p2ns.ping/pong), and core request lifecycle on RPC open. Update
global.profile and example.plugin, admin Plugin RPC stats, docs, and
test:plugin-rpc. Breaking: upgrade all peers together; no legacy adapters.
This commit is contained in:
Raven Scott
2026-05-28 11:55:01 -04:00
parent ba44ef267d
commit 6ee20a3f68
18 changed files with 778 additions and 1651 deletions
+24 -19
View File
@@ -92,34 +92,36 @@ function renderStats() {
});
}
// Render Peer Channels stats
function renderPeerChannelsStats(peerChannels) {
// Update summary cards
// Render Plugin RPC stats (stats.peerChannels / stats.pluginRpc)
function renderPluginRpcStats(peerChannels) {
const totalPluginsEl = document.getElementById('peer-channels-total-plugins');
const totalProtocolsEl = document.getElementById('peer-channels-total-protocols');
const openChannelsEl = document.getElementById('peer-channels-open');
const closedChannelsEl = document.getElementById('peer-channels-closed');
const methodsEl = document.getElementById('peer-channels-methods');
const detailsContainer = document.getElementById('peer-channels-details');
if (totalPluginsEl) totalPluginsEl.textContent = peerChannels?.totalPlugins || 0;
if (totalProtocolsEl) totalProtocolsEl.textContent = peerChannels?.totalProtocols || 0;
if (openChannelsEl) openChannelsEl.textContent = peerChannels?.openChannels || 0;
if (closedChannelsEl) closedChannelsEl.textContent = peerChannels?.closedChannels || 0;
if (openChannelsEl) openChannelsEl.textContent = peerChannels?.rpcOpen ?? peerChannels?.openChannels ?? 0;
if (methodsEl) methodsEl.textContent = peerChannels?.totalMethods ?? 0;
if (!detailsContainer) return;
if (!peerChannels || !peerChannels.plugins || peerChannels.plugins.length === 0) {
detailsContainer.innerHTML = '<p class="theme-text-tertiary text-center">No peer channels registered</p>';
detailsContainer.innerHTML = '<p class="theme-text-tertiary text-center">No plugin RPC protocols registered</p>';
return;
}
detailsContainer.innerHTML = peerChannels.plugins.map(plugin => {
const protocolsHtml = plugin.protocols.map(protocol => {
const statusColor = protocol.openCount > 0 ? 'bg-green-500' : 'bg-gray-500';
const statusColor = (protocol.rpcOpenCount ?? protocol.openCount) > 0 ? 'bg-green-500' : 'bg-gray-500';
const methodsLabel = (protocol.methods && protocol.methods.length)
? protocol.methods.join(', ')
: '(no plugin methods)';
const peersHtml = protocol.peers.length > 0 ? protocol.peers.map(peer => {
const peerStatusColor = peer.status === 'open' ? 'text-green-500' :
const peerStatusColor = peer.rpcReady || peer.status === 'open' ? 'text-green-500' :
peer.status === 'connecting' ? 'text-yellow-500' : 'text-red-500';
const peerStatusIcon = peer.status === 'open' ? 'fa-circle-check' :
const peerStatusIcon = peer.rpcReady || peer.status === 'open' ? 'fa-circle-check' :
peer.status === 'connecting' ? 'fa-spinner fa-spin' : 'fa-circle-xmark';
return `
<div class="flex items-center justify-between p-2 theme-glass rounded text-sm">
@@ -128,25 +130,25 @@ function renderPeerChannelsStats(peerChannels) {
<span class="font-mono">${peer.peerId}</span>
</div>
<div class="flex items-center gap-4 text-xs theme-text-secondary">
<span>Local: ${peer.localOpened ? '✓' : '✗'}</span>
<span>Remote: ${peer.remoteOpened ? '✓' : '✗'}</span>
${peer.reopenAttempts > 0 ? `<span class="text-yellow-500">Reopens: ${peer.reopenAttempts}</span>` : ''}
<span>RPC: ${peer.rpcReady ? '✓' : '✗'}</span>
<span>Conn: ${peer.connectionValid ? '✓' : '✗'}</span>
${peer.reopenAttempts > 0 ? `<span class="text-yellow-500">Reopens: ${peer.reopenAttempts}</span>` : ''}
</div>
</div>
`;
}).join('') : '<p class="text-sm theme-text-tertiary p-2">No peers connected</p>';
const openCount = protocol.rpcOpenCount ?? protocol.openCount ?? 0;
return `
<div class="mb-3">
<div class="flex items-center gap-2 mb-2">
<div class="flex items-center gap-2 mb-2 flex-wrap">
<span class="w-2 h-2 rounded-full ${statusColor}"></span>
<span class="font-semibold">${protocol.fullName}</span>
<span class="text-xs theme-text-secondary">(${protocol.encoding})</span>
<span class="text-xs theme-text-secondary font-mono">${methodsLabel}</span>
<span class="text-xs px-2 py-0.5 rounded ${protocol.autoReconnect ? 'bg-blue-500/20 text-blue-400' : 'bg-gray-500/20 text-gray-400'}">
${protocol.autoReconnect ? 'Auto-reconnect' : 'Manual'}
</span>
<span class="text-xs theme-text-secondary ml-auto">${protocol.openCount}/${protocol.peerCount} open</span>
<span class="text-xs theme-text-secondary ml-auto">${openCount}/${protocol.peerCount} RPC open</span>
</div>
<div class="space-y-1 ml-4">
${peersHtml}
@@ -644,9 +646,8 @@ function updateStatsDisplay(stats, historical) {
window.renderHolesailChildren(stats.holesailChildren || []);
}
// Peer Channels
if (stats.peerChannels) {
renderPeerChannelsStats(stats.peerChannels);
if (stats.peerChannels || stats.pluginRpc) {
renderPluginRpcStats(stats.pluginRpc || stats.peerChannels);
}
// HyperDB
@@ -1493,6 +1494,10 @@ window.requestStatsSnapshotViaWebSocket = requestStatsSnapshotViaWebSocket;
window.renderStats = renderStats;
window.updateStatsDisplay = updateStatsDisplay;
window.renderHolesailChildren = renderHolesailChildren;
function renderPeerChannelsStats(peerChannels) {
return renderPluginRpcStats(peerChannels);
}
window.renderPluginRpcStats = renderPluginRpcStats;
window.renderPeerChannelsStats = renderPeerChannelsStats;
window.renderCoreStats = renderCoreStats;
window.renderHyperDBStats = renderHyperDBStats;