Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

QMP server - Connection Refused bug. #172

Closed
fredyshox opened this issue Mar 24, 2020 · 2 comments
Closed

QMP server - Connection Refused bug. #172

fredyshox opened this issue Mar 24, 2020 · 2 comments
Labels
bug Something isn't working
Milestone

Comments

@fredyshox
Copy link
Contributor

fredyshox commented Mar 24, 2020

Describe the bug
Related to pull request that I'm currently working on #113

[_qemu_system startWithCompletion:^(BOOL success, NSString *msg){
if (!success) {
[self errorTriggered:msg];
}
dispatch_semaphore_signal(self->_qemu_exit_sema);
}];
int tries = kMaxConnectionTries;
do {
[NSThread sleepForTimeInterval:0.1f];
if ([_spice_connection connect]) {
break;
}
} while (tries-- > 0);
if (tries == 0) {
[self errorTriggered:NSLocalizedString(@"Failed to connect to display server.", @"UTMVirtualMachine")];
}
[self->_qemu connect];

When the code between _qemu_system startWithCompletion: and _qemu connect, executes quickly enough (in my case serial console connection don't take much time), UTMJSONStream will fail to connect with Connection Refused error, because it is happening before qemu manages to start QMP server. In my code I duct taped it using NSThread sleep, but it's not perfect solution 😄.

Possible solution
One possible solution is to design reconnection mechanism in UTMJSONStream.

- (void)connect {
CFReadStreamRef readStream;
CFWriteStreamRef writeStream;
CFStreamCreatePairWithSocketToHost(kCFAllocatorDefault, (__bridge CFStringRef)self.host, self.port, &readStream, &writeStream);
@synchronized (self) {
_inputStream = CFBridgingRelease(readStream);
_outputStream = CFBridgingRelease(writeStream);
_data = [NSMutableData data];
_parsedBytes = 0;
_open_curly_count = -1;
[_inputStream setDelegate:self];
[_inputStream scheduleInRunLoop:[NSRunLoop mainRunLoop] forMode:NSDefaultRunLoopMode];
[_inputStream open];
[_outputStream setDelegate:self];
[_outputStream scheduleInRunLoop:[NSRunLoop mainRunLoop] forMode:NSDefaultRunLoopMode];
[_outputStream open];
}
}

  • Specify number of trials in connect
  • Retry _inputStream/_outputStream open, after receiving NSStreamEventErrorOccurred and Connection refused NSError until number of trials is exceeded or NSStreamEventOpenCompleted is received.
@osy osy added the bug Something isn't working label Mar 24, 2020
@osy osy added this to the v0.7 milestone Mar 24, 2020
@osy
Copy link
Contributor

osy commented Mar 24, 2020

Thanks this may also be the issue in #130

@osy
Copy link
Contributor

osy commented Mar 25, 2020

Apple's API really sucks here. Why can't they return an error immediately if the connection fails? The code becomes real messy if we have to implement some state to track "are we retrying connection".

@osy osy closed this as completed in 9749fcb Mar 25, 2020
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working
Projects
None yet
Development

No branches or pull requests

2 participants