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

Make validating a bundle thread-safe #237

Merged
merged 1 commit into from
Jun 2, 2021

Conversation

carolynvs
Copy link
Contributor

Background:
The jsonschema library we use is not thread-safe: qri-io/jsonschema#80. This prevents callers from validating and working with bundles concurrently.

Current Fix:
I made a fork of the latest version jsonschema and tweaked it so that it doesn't use package variables for everything, and uses a lock when it does access the global schema. I'm not sure if that is a solution that they will merge, still waiting on a reply. We are still using unreleased commits on docker repos so at least there is precedent. 😀

The other changes you see in the PR are due to changes in the latest version of jsonschema.

I tried to fix this without changing jsonschema and wasn't successful. However I am not sure how we feel about using a fork of jsonschema when the patch may never get merged, or the upstream bug fixed.

We really needed this in Porter, so either way I'm maintaining the fork... 🤷‍♀️

Copy link
Member

@vdice vdice left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks good, just curious about some of the updates per the newer jsonschema lib...

// Validate implements the Validator interface for ContentEncoding
// which, as of writing, isn't included by default in the jsonschema library we consume
func (c ContentEncoding) Validate(propPath string, data interface{}, errs *[]jsonschema.ValError) {
func (c ContentEncoding) Validate(propPath string, data interface{}, errs *[]jsonschema.KeyError) {}
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is this the standard approach then with the latest jsonschema lib version? Have Validate be a no-op and place all logic in ValidateKeyword?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Probably not! Sorry about that, I followed what they did in the tests to define a custom keyword and I didn't dig further. Looks like there may be more that can be done.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Here was their example for making a custom keyword:

https://github.com/qri-io/jsonschema/blob/master/README.md#custom-keywords

They just implemented ValidateKeyword and left the other functions empty.

I looked at a few implementations of string keywords and most also leave those functions empty.

https://github.com/qri-io/jsonschema/blob/dbc3af1d666cc034a9ac89f10fba0ad6d5cb6c8e/keywords_string.go#L17-L27

An example of a keyword that does implement Register and resolve is anyOf which allows you to nest a subschema inside the keyword. That doesn't apply here though.

I don't think that the ContentEncoding keyword needs to implement them but if you see something that we should be doing in those functions, let me know. The doc is a bit scarce so I'm piecing it together from usage.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ah, thank you for the references. Indeed, it looks like what you've done for ContentEncoding should be the right approach. 👍

bundle/definition/validators.go Show resolved Hide resolved
@radu-matei
Copy link
Member

I assume there are not other JSON schema libraries that are thread-safe?

Do you have any preference to maintaining the fork in your account, or in this organization?
(I'm hoping you wouldn't be the only one responsible for updating it if it were in this organization.)

@carolynvs
Copy link
Contributor Author

The other library is https://github.com/xeipuuv/gojsonschema. They don't say that they are threadsafe, there are still open issues with people asking about that or reporting errors (without reproduction). I like the idea of trying it out and seeing if it would work for us. Let me give that a try and see if it blows up or not.

@carolynvs
Copy link
Contributor Author

Update: Both libraries need more patches to address threadsafety and also neither is making progress towards accepting any patches.

Another cnab-go user, @dataoleg, has run into problems with this bug. Since the "better" fix than this patch isn't forthcoming, I would like to see us merge this PR here so that at least cnab-go users are no longer affected.

* Use fork of jsconschema library with a fix for threadsafe calls to
validate. https://github.com/carolynvs/jsonschema/tree/local-keyword-registry

Signed-off-by: Carolyn Van Slyck <me@carolynvanslyck.com>
@carolynvs carolynvs merged commit c9aabe2 into cnabio:main Jun 2, 2021
@carolynvs carolynvs deleted the jsonschema-lock branch June 2, 2021 15:14
This pull request was closed.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants