feat: live updates
This commit is contained in:
@@ -21,45 +21,124 @@ class ClusterViewModel extends ViewModel {
|
||||
setTimeout(() => {
|
||||
this.updatePrimaryNodeDisplay();
|
||||
}, 100);
|
||||
|
||||
// Set up WebSocket listeners for real-time updates
|
||||
this.setupWebSocketListeners();
|
||||
}
|
||||
|
||||
// Set up WebSocket event listeners
|
||||
setupWebSocketListeners() {
|
||||
if (!window.wsClient) {
|
||||
logger.warn('WebSocket client not available');
|
||||
return;
|
||||
}
|
||||
|
||||
// Listen for cluster updates
|
||||
window.wsClient.on('clusterUpdate', (data) => {
|
||||
logger.debug('ClusterViewModel: Received WebSocket cluster update:', data);
|
||||
|
||||
// Update members from WebSocket data
|
||||
if (data.members && Array.isArray(data.members)) {
|
||||
const onlineNodes = data.members.filter(m => m && m.status && m.status.toUpperCase() === 'ACTIVE').length;
|
||||
|
||||
logger.debug(`ClusterViewModel: Updating members from ${this.get('members')?.length || 0} to ${data.members.length} members`);
|
||||
|
||||
this.batchUpdate({
|
||||
members: data.members,
|
||||
lastUpdateTime: data.timestamp || new Date().toISOString(),
|
||||
onlineNodes: onlineNodes
|
||||
});
|
||||
|
||||
// Update primary node display if it changed
|
||||
if (data.primaryNode !== this.get('primaryNode')) {
|
||||
logger.debug(`ClusterViewModel: Primary node changed from ${this.get('primaryNode')} to ${data.primaryNode}`);
|
||||
this.set('primaryNode', data.primaryNode);
|
||||
this.set('totalNodes', data.totalNodes || 0);
|
||||
}
|
||||
} else {
|
||||
logger.warn('ClusterViewModel: Received cluster update but no valid members array:', data);
|
||||
}
|
||||
});
|
||||
|
||||
// Listen for node discovery events
|
||||
window.wsClient.on('nodeDiscovery', (data) => {
|
||||
logger.debug('ClusterViewModel: Received WebSocket node discovery event:', data);
|
||||
|
||||
if (data.action === 'discovered') {
|
||||
// A new node was discovered - trigger a cluster update
|
||||
setTimeout(() => {
|
||||
this.updateClusterMembers();
|
||||
}, 500);
|
||||
} else if (data.action === 'stale') {
|
||||
// A node became stale - trigger a cluster update
|
||||
setTimeout(() => {
|
||||
this.updateClusterMembers();
|
||||
}, 500);
|
||||
}
|
||||
});
|
||||
|
||||
// Listen for connection status changes
|
||||
window.wsClient.on('connected', () => {
|
||||
logger.debug('ClusterViewModel: WebSocket connected');
|
||||
// Optionally trigger an immediate update when connection is restored
|
||||
setTimeout(() => {
|
||||
this.updateClusterMembers();
|
||||
}, 1000);
|
||||
});
|
||||
|
||||
window.wsClient.on('disconnected', () => {
|
||||
logger.debug('ClusterViewModel: WebSocket disconnected');
|
||||
});
|
||||
}
|
||||
|
||||
// Update cluster members
|
||||
async updateClusterMembers() {
|
||||
try {
|
||||
logger.debug('ClusterViewModel: updateClusterMembers called');
|
||||
|
||||
|
||||
// Check if we have recent WebSocket data (within last 30 seconds)
|
||||
const lastUpdateTime = this.get('lastUpdateTime');
|
||||
const now = new Date();
|
||||
const websocketDataAge = lastUpdateTime ? (now - new Date(lastUpdateTime)) : Infinity;
|
||||
|
||||
// If WebSocket data is recent, skip REST API call to avoid conflicts
|
||||
if (websocketDataAge < 30000 && this.get('members').length > 0) {
|
||||
logger.debug('ClusterViewModel: Using recent WebSocket data, skipping REST API call');
|
||||
return;
|
||||
}
|
||||
|
||||
// Store current UI state before update
|
||||
const currentUIState = this.getAllUIState();
|
||||
const currentExpandedCards = this.get('expandedCards');
|
||||
const currentActiveTabs = this.get('activeTabs');
|
||||
|
||||
|
||||
this.set('isLoading', true);
|
||||
this.set('error', null);
|
||||
|
||||
|
||||
logger.debug('ClusterViewModel: Fetching cluster members...');
|
||||
const response = await window.apiClient.getClusterMembers();
|
||||
logger.debug('ClusterViewModel: Got response:', response);
|
||||
|
||||
|
||||
const members = response.members || [];
|
||||
const onlineNodes = Array.isArray(members)
|
||||
? members.filter(m => m && m.status && m.status.toUpperCase() === 'ACTIVE').length
|
||||
: 0;
|
||||
|
||||
|
||||
// Use batch update
|
||||
this.batchUpdate({
|
||||
members: members,
|
||||
lastUpdateTime: new Date().toISOString(),
|
||||
onlineNodes: onlineNodes
|
||||
});
|
||||
|
||||
|
||||
// Restore expanded cards and active tabs
|
||||
this.set('expandedCards', currentExpandedCards);
|
||||
this.set('activeTabs', currentActiveTabs);
|
||||
|
||||
|
||||
// Update primary node display
|
||||
logger.debug('ClusterViewModel: Updating primary node display...');
|
||||
await this.updatePrimaryNodeDisplay();
|
||||
|
||||
|
||||
} catch (error) {
|
||||
console.error('ClusterViewModel: Failed to fetch cluster members:', error);
|
||||
this.set('error', error.message);
|
||||
|
||||
Reference in New Issue
Block a user