I have an endpoint that鈥檚 timing out when using Moya.
getApiProvider().request(.getOrder(id: 4))
.subscribe { i in
print(i)
}
No errors, just the following in the console:
2016-12-17 12:19:20.223132 TestApp[46055:1474324] [] nw_endpoint_flow_service_writes [3.1 176.34.225.3:80 ready socket-flow (satisfied)] Write request has 4294967295 frame count, 0 byte count
I don't see any logs showing this particular request on the server, and other requests from Moya are working fine.
When I perform an identical request with Alamofire...
Alamofire.request(
"http://localhost:3000/api/v1/assistants/order?order_id=4",
method: HTTPMethod.get,
parameters: nil,
encoding: JSONEncoding.default,
headers: [ "Authorization" : "Bearer <token>" ]
)
.response(completionHandler: { response in
print(JSON(data: response.data!))
})
...the request completes without issue.
I'm sure it's likely something simple I'm overlooking - any ideas what may be causing this?
Thanks for providing all the details. You could try adding the NetworkLogger plugin to see if that reports anything.
Also, which version of Moya are you using?
@BasThomas
Thanks for your quick reply! NetworkLogger doesn't really add anything extra info - in fact at the moment it's not showing any request at all.
I'm using Moya/Swift ~> 8.0.0-beta.4 - should I give the latest version a go?
Although I am not aware of anything that might fix this particular issue, please give it a go :)
@BasThomas ah, now I remember why I'm tied to this version: I'm pairing Moya with Moya-SwiftyJSONMapper which specifies beta.4
Hey @jonlambert, Moya-SwiftyJSONMapper has been updated for beta.6. Could you try with that version and see if that makes a difference?
Thanks @BasThomas but I've just updated, no luck I'm afraid! Still getting the same issues. Is my parameters property specified correctly?
Hmm, I see your API.swift file uses POST instead of GET, might that cause the issue?
@BasThomas ah that was a mistake when I tidied it up! It's specified as GET in the actual file. I'll edit the file attached accordingly.
Hmm, don't see anything that'd cause it, then. @Moya/contributors, any ideas?
@jonlambert it looks to me like an Rx issue. Are you adding your subscription to a disposeBag?
@AndrewSB Yep - problem occurs both with and without the subscription being added to a DisposeBag.
@jonlambert Any chance you could create a public repo that reproduces the problem? I'd jump in and do some debugging.
Also, one thing to note... while your Alamofire.request example specifies JSONEncoding, you are manually encoding the parameters in the URL. In the Moya instance, these will instead be encoded as JSON in the HTTP body. This might not make a difference depending on your API code.
I've actually run into a similar issue, only it's much more spotty than what OP describes... it happens occasionally on my sign in request. I'm using ReactiveSwift and ReactiveCocoa with ReactiveMoya. My network request is wrapped in an Action<(), String, AuthenticationError>, and it seems to be invoked, because my button disables properly, but no network requests show up on the server, in the network logger, in my local proxy, or anywhere. I have to leave the app and come back, which for whatever reason, forces the Action to send an error.
Typically, this will fix itself with a few tries of leaving the app and coming back.
We've been trying to chase this bug down for MONTHS, but have such a hard time trying to reproduce it.
@jonlambert: could it have anything to do with creating a new provider and then immediately using it? Could you try creating your Provider, and then dispatching your network request a second later, as an experiment, to see if it changes anything?
@justinmakaila: sounds like a headache 馃槙
@justinmakaila I've had this issue sporadically too, just this time (luckily or unluckily?) it's consistently failing so I can examine it further.
@scottrhoyt I will certainly try and put together a repro tomorrow (I'm on UK time at the moment). I expect accurately reproducing the server's behaviour might be a bit difficult if it's a server quirk throwing Moya off - but I'll give it a go nonetheless.
That's a great point about the JSONEncoding. I'll look into that now!
@AndrewSB I've tested that with a 5 second delay to no avail unfortunately. Still the same timeout. 馃槙
@scottrhoyt Just tried your suggestion this morning - that fixed it!
let endpoint = Endpoint<ToshiAPI>(
url: url,
sampleResponseClosure: {.networkResponse(200, target.sampleData)},
method: target.method,
parameters: target.parameters,
parameterEncoding: target.method == .get ? URLEncoding.default : JSONEncoding.default
)
Looks like there's an issue with Alamofire timing out when sending GET requests using Alamofire with JSON in the body: https://github.com/Alamofire/Alamofire/issues/1530, https://github.com/Alamofire/Alamofire/issues/1819
If you guys think this use case is common enough then this conditional is fine; perhaps I could add a pointer in the documentation though.
Otherwise I'd be happy to discuss other ways of handling this automatically when using JSONEncoding 馃憤 (Although perhaps that's an issue for Alamofire itself)
Thank you so much everyone for your help!
Hmm... that doesn't fix it for me. If I get a re-creatable test case, I'll open a new issue.
If you get a reproducible error @justinmakaila I'd be interested in following along. I have a feeling this isn't the same bug as the sporadical timeout.
@jonlambert, glad to hear that worked for you! With the introduction of #859, you can now set your parameterEncoding directly in your TargetType. This change is currently only available on master.
Reopening issue - it worked in the instance above but I'm getting the same error using it elsewhere in the code. Looks like a similar scenario to @justinmakaila.
Sorry to hear the issue is back. My recommendation would be to enable curl output on the NetworkLoggerPlugin, add it to your provider, and use the curl output to test the requests from your CLI to diagnose the problem. If you aren't seeing any output from the logging plugin, then something is probably going wrong on the Moya side and might be able to be reproduced in a sample repo for us to debug.
@scottrhoyt There's no output from the logging plugin when I make the request - I'll attempt to reproduce the issue as soon as I can!
@scottrhoyt
I have attempted to reproduce the issue, the repository can be found here: https://github.com/jonlambert/MoyaIssue844
@jonlambert I set up a few breakpoints in your project and ran into this curious situation:

it looks like the provider is nil at the point of creating the Observable
EDIT (addition?): That's probably due to the fact that the provider is out of scope at the end of download() on the view model. I'm going to try keeping the provider around...
@jonlambert Updating your view model code to:
class WelcomeViewModel: NSObject {
let provider: RxMoyaProvider<API>
override init() {
provider = RxMoyaProvider<API>(
endpointClosure: MoyaProvider.defaultEndpointMapping,
requestClosure: MoyaProvider.defaultRequestMapping,
stubClosure: MoyaProvider.neverStub,
manager: RxMoyaProvider<API>.defaultAlamofireManager(),
plugins: [NetworkLoggerPlugin(cURL: true)],
trackInflights: true
)
super.init()
}
func download() -> Observable<Moya.Response> {
return provider.request(.ping)
}
}
Results in expected behavior:
2017-01-10 17:48:01.958: WelcomeViewController.swift:39 (viewDidLoad()) -> subscribed
["$ curl -i \\\n\t-H \"Accept-Language: en;q=1.0\" \\\n\t-H \"User-Agent: MoyaIssue844/1.0 (co.evada.MoyaIssue844; build:1; iOS 10.2.0) Alamofire/4.2.0\" \\\n\t-H \"Accept-Encoding: gzip;q=1.0, compress;q=0.5\" \\\n\t\"https://hookb.in/Z6mo35ag/?foo=bar\""]
[["Moya_Logger: [10/01/2017 17:48:16] Response: <NSHTTPURLResponse: 0x608000039320> { URL: https://hookb.in/Z6mo35ag/?foo=bar } { status code: 200, headers {\n \"Access-Control-Allow-Origin\" = \"*\";\n \"Cache-Control\" = \"private, no-cache, no-store, must-revalidate\";\n \"Content-Length\" = 16;\n \"Content-Type\" = \"application/json; charset=utf-8\";\n Date = \"Tue, 10 Jan 2017 22:48:17 GMT\";\n Expires = \"-1\";\n Pragma = \"no-cache\";\n Server = nginx;\n \"Strict-Transport-Security\" = \"max-age=31536000; includeSubdomains; preload\";\n \"access-control-allow-headers\" = \"Origin, X-Requested-With, Content-Type, Accept\";\n \"access-control-allow-methods\" = \"GET, PUT, POST, DELETE\";\n \"x-expires-at\" = \"Tue, 17 Jan 2017 16:25:02 GMT\";\n \"x-ratelimit-limit\" = 1000;\n \"x-ratelimit-remaining\" = 999;\n \"x-ratelimit-reset\" = 3600;\n \"x-ua-compatible\" = \"IE=Edge,chrome=1\";\n} }"]]
2017-01-10 17:48:18.035: WelcomeViewController.swift:39 (viewDidLoad()) -> Event next(Status Code: 200, Data Length: 16)
Status Code: 200, Data Length: 16
2017-01-10 17:48:18.035: WelcomeViewController.swift:39 (viewDidLoad()) -> Event completed
2017-01-10 17:48:18.035: WelcomeViewController.swift:39 (viewDidLoad()) -> isDisposed
Thanks for the investigation @justinmakaila! This is quite related to the issue brought up in #905.
Side note: I don't think this is exactly related to the sporadic issue. In fact, while playing with this project, my team reported that they encountered the bug again. Requests began appearing in a proxy they had set up within 15-90 seconds of the initial "stumble". Still trying to dig in.
@jonlambert I had similar issue. tried curl command with same result.
there's been 2 issues:
I changed the code that @justinmakaila provided a little bit and it worked for me:
let endpointClosure = { (target: GitHub) -> Endpoint<GitHub> in
let defaultEndpoint = MoyaProvider.defaultEndpointMapping(for: target)
return defaultEndpoint.adding(newHTTPHeaderFields: ["Accept-Encoding": "application/json"])
}
provider = RxMoyaProvider<GitHub>(
endpointClosure: endpointClosure,
requestClosure: MoyaProvider.defaultRequestMapping,
stubClosure: MoyaProvider.neverStub,
manager: RxMoyaProvider<GitHub>.defaultAlamofireManager(),
plugins: [NetworkLoggerPlugin(cURL: true)],
trackInflights: true
)
Also if your request is get then make sure to return nil for the parameters like this:
public var parameters: [String : Any]? { return nil }
obviously you can add switch case for different entries
This issue has been marked as stale because it has not had recent activity. It will be closed if no further activity occurs.
This issue has been auto-closed because there hasn't been any activity for 59 days. However, we really appreciate your contribution, so thank you for that! 馃檹 Also, feel free to open a new issue if you still experience this problem 馃憤.
Most helpful comment
@scottrhoyt Just tried your suggestion this morning - that fixed it!
Looks like there's an issue with Alamofire timing out when sending
GETrequests using Alamofire with JSON in the body: https://github.com/Alamofire/Alamofire/issues/1530, https://github.com/Alamofire/Alamofire/issues/1819If you guys think this use case is common enough then this conditional is fine; perhaps I could add a pointer in the documentation though.
Otherwise I'd be happy to discuss other ways of handling this automatically when using JSONEncoding 馃憤 (Although perhaps that's an issue for Alamofire itself)
Thank you so much everyone for your help!