hasSpaceAvailable become "false" and no failure blocks are called by kcharwood · Pull Request #2496 · AFNetworking/AFNetworking · GitHub
Skip to content
This repository was archived by the owner on Jan 17, 2023. It is now read-only.

hasSpaceAvailable become "false" and no failure blocks are called#2496

Merged
kcharwood merged 1 commit into
masterfrom
2496
Oct 13, 2015
Merged

hasSpaceAvailable become "false" and no failure blocks are called#2496
kcharwood merged 1 commit into
masterfrom
2496

Conversation

@kcharwood

Copy link
Copy Markdown
Contributor

I'm using AFNetworking (2.5.0) via Cocoapod in an iOS >7.0 application.
I need to download a binary file so i configured the outputStream property

AFHTTPRequestOperation *op = [self.operationManager GET:url
                                                 parameters:nil
                                                    success:^(AFHTTPRequestOperation *operation, id responseObject) {
                                                    } failure:^(AFHTTPRequestOperation *operation, NSError *error) {

            }];
op.outputStream = [NSOutputStream outputStreamToFileAtPath:tempPath append:YES];

90% of the times it works correctly, but in some case the line AFURLConnectionOperation.m@655 became false (i put a breakpoint) and the library enters in an endless loop and no failure blocks are called.

I put here the current implementation of the method

NSUInteger length = [data length];
    while (YES) {
        NSInteger totalNumberOfBytesWritten = 0;
        if ([self.outputStream hasSpaceAvailable]) {
            const uint8_t *dataBuffer = (uint8_t *)[data bytes];

            NSInteger numberOfBytesWritten = 0;
            while (totalNumberOfBytesWritten < (NSInteger)length) {
                numberOfBytesWritten = [self.outputStream write:&dataBuffer[(NSUInteger)totalNumberOfBytesWritten] maxLength:(length - (NSUInteger)totalNumberOfBytesWritten)];
                if (numberOfBytesWritten == -1) {
                    break;
                }

                totalNumberOfBytesWritten += numberOfBytesWritten;
            }

            break;
        } 

        if (self.outputStream.streamError) {
            [self.connection cancel];
            [self performSelector:@selector(connection:didFailWithError:) withObject:self.connection withObject:self.outputStream.streamError];
            return;
        }
    }

I think that if [self.outputStream hasSpaceAvailable] is false (for some reason) but there is not error on the outputStream the while() enters in an infinite loop.

mattt added a commit that referenced this pull request Feb 14, 2015
@pdavid0

pdavid0 commented Jun 16, 2015

Copy link
Copy Markdown

@ignazioc

Copy link
Copy Markdown
Author

it should be already in the current version because was fixed by mattt on 14 feb.

@pdavid0

pdavid0 commented Jun 17, 2015

Copy link
Copy Markdown

@nartex

nartex commented Aug 25, 2015

Copy link
Copy Markdown

@kcharwood kcharwood added this to the 2.7.0 milestone Aug 25, 2015
@kcharwood

Copy link
Copy Markdown
Contributor

Sorry I missed this issue. I'll get it updated soon. Thanks!

@nielsvroegindeweij

Copy link
Copy Markdown

I'm also having this same issue, about 10% of the times. In my tests, the problem seems to be related with low disk space on the device. Although I think this wasn't the case in all the tests. Maybe low disk space or low memory is the reason why NSOutputstream doesn't accept any more data?

I also used the provided fix, but I'm not completely sure about it(maybe I just don't understand the way this works):

  • When NSOutputStream hasn't any space avalable the fix will immediately cancel the connection and return. Couldn't it be the NSOutputStream just didn't have enough time to write data to file or memory and need some loops to have space available again?
  • When the outputstream hasn't space available and cancels the connection, most of the times the stream error property is not set. Although this will stop the endless looping, the failure or success method aren't called. As a result, the app will not be able to further handle this situation.

Maybe there is a way to recognize why hasSpaceAvailable stays false and provide this information to the failure block?

@kcharwood kcharwood modified the milestones: 2.6.1, 2.7.0 Oct 13, 2015
@kcharwood

Copy link
Copy Markdown
Contributor

I'l get this one in today. Hopefully will cut a release before EOD

kcharwood added a commit that referenced this pull request Oct 13, 2015
hasSpaceAvailable become "false" and no failure blocks are called
@kcharwood kcharwood merged commit 50f01e2 into master Oct 13, 2015
@kcharwood kcharwood deleted the 2496 branch October 13, 2015 18:57
@kcharwood

Copy link
Copy Markdown
Contributor

Not needed in the 3_0_0 branch since AFURLConnectionOperation has been removed.

@RbBtSn0w

Copy link
Copy Markdown

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

6 participants