-
Notifications
You must be signed in to change notification settings - Fork 114
Type-safe parsing of JSON response #1127
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
Conversation
YuriyVelichkoPI
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Please, remove PBM prefix in new Swift classes.
Since we are switching converting JSON to Swift. can we use advantages of Codable?
|
Its possible to use codable, but in my experience Codable tends to be too strict for most uses. In our case I think we want to prioritize successful parsing of response objects over enforcing strict conformance to the response spec. If for example for some field the response contains You could loosen strictness in these cases, but this is not the default behavior and you would need to write your own custom decoding logic and the end result is usually harder to read and more error prone than alternatives. |
|
@YuriyVelichkoPI Can we hold up on this PR and prioritize merging in the SPM migration PRs? Those PRs include the swift migration part of this PR, and I'd like to avoid having to do a rebase/merge. I can add back in the custom class feature afterwards. |
Thanks for the clarification. Makes sense. We can try Codable later. |
Hi @jclou ! Do you want to move forward with this PR since a couple of PRs for SPM are already merged? |
|
Hi @jclou @mdanylov-sigma ! What are the plans for this PR? I noticed that many classes were rewritten in Swift as part of the migration to SPM, but I didn't verify the alignment of functional requirements between this PR and the changes for SPM. Are you going to reimplement this one based on the new files, or is everything already done and this PR can be closed? |
|
Hi @jclou, @mdanylov-sigma, what is the status of this PR? |
In our latest conversation with James, he mentioned that he wanted to update the PR, since it includes custom parsing that could be useful to have. @jclou Are you able to wrap up the work you’ve done so we can merge it? |
|
Sorry, I forgot about this PR. The type safety from moving to Swift is already in now SPM migration. I'll try to find some time next week to rebase this for the custom parsing feature. |
db9093c to
2304666
Compare
|
Where can I see which tests are failing? I suspect they aren't related to my changes. |
There was an internal runner error, it works after re-running. |
YuriyVelichkoPI
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Also, please, add the short description of custom types utilization into the documentation, I think we can put it on this page:
https://docs.prebid.org/prebid-mobile/pbm-api/ios/pbm-targeting-ios.html
The repository to update the doc: https://github.com/prebid/prebid.github.io
| subscript<T: PBMJsonCodable>(_ key: Key) -> T? { | ||
| get { | ||
| (dict[key.rawValue] as? [String : Any]).flatMap { T.init(jsonDictionary: $0) } | ||
| (dict[key.rawValue] as? [String : Any]).flatMap { CustomModelObjects.instantiate(json: $0) } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
How much does this instantiation affect parsing performance, given that it involves a synchronous operation under the hood?
Could you run benchmarks before and after this change and share the results here, so we can confirm that it’s optimal?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@YuriyVelichkoPI
We're using synchronization here to prevent a crash, but in practice apps will very likely just register a custom type once (if at all) before using PBM, and so lock contention for reads should be practically zero.
The fast path (i.e. no lock contention) performance of pthread_rwlock is very fast. But anyway I did a few runs of creating BidResponse objects. The bid response is nested with other types that also can have custom types and therefore go through the lock code, so each bid response performs 37 locks+unlocks. I also included in the testing os_unfair_lock which has less overhead, but can cause lock contention on simultaneous reads. This would happen if if PBM is parsing multiple responses simultaneously, which I is likely a fairly common use case.
Each run creates 1000 BidResponses. Time is in seconds. I ran this on a simulator with the normal test configuration, so we should expect faster performance on real devices and with compiler optimizations turned on.
no locking
0.08809900283813477
0.08694291114807129
0.08736598491668701
0.08878195285797119
pthread_rw_lock
0.08940601348876953
0.08895599842071533
0.08983302116394043
0.0893028974533081
os_unfair_lock
0.09004998207092285
0.08857595920562744
0.08893299102783203
0.08905899524688721
It's basically a wash. Maybe we can say there's a one or two micro second overhead for each BidResponse
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hi @jclou, Thanks for the detailed information and for running the validation - it’s very helpful from both a strategic and reasoning perspective. In theory, many things look different than in practice, so when we provide a tool, we need to be sure we’ve done everything correctly from a practical point of view.
Having benchmarks here in the PR will be very useful, so we can reference them anytime we need to prove that performance is not actually impacted.
And thanks for the docs.
|
Documentation update PR here: |
YuriyVelichkoPI
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM
mdanylov-sigma
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM!
Changes:
JSONParsing.swiftkeep the model object code simple and ensure consistent and type-safe conversions to and from JSON.Additions:
Fixes:
-Made
PBMORTBAbstractResponse.extnullable to handle the case in-[PBMORTBAbstractResponse initWithJsonDictionary:extParser]where it does not get set. This case previously existed in tests, but after migratingPBMORTBBidExtto swift, the nil objc class instance instead became an uninitialized Swift class instance and crashed.-[PBMAbstractCreative handleClickthrough:sdkConfiguration:completionHandler:onExit:]Documentation Change:
prebid/prebid.github.io#6344