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

Simplify the implementation of IOHandler #602

Merged
merged 5 commits into from
May 6, 2021

Conversation

gschwind
Copy link
Collaborator

Overview

The current implementation use a tricks that manipulate the mro.
This trick do not have any obvious benefit and make the code much more
complicated than necessary. This patch simplifier the implementation by
replacing the tricky class change to a change in mamber's variable.

Related Issue / Discussion

Following discussion in #598, Here is my proposal of refactoring the IOHandler. It come in two flavor, one with is a basic one and a second using weakref. I thought of another way using only class object without instantiating them like the previous implementation but I don't like too much the idea.

The code pass all the test excluding two. the two failed test a due to the fact that the test use private API to trick the test checking, thus IMO this just the test that is invalid.

Best regards.

Additional Information

Contribution Agreement

(as per https://github.com/geopython/pywps/blob/master/CONTRIBUTING.rst#contributions-and-licensing)

  • I'd like to contribute [feature X|bugfix Y|docs|something else] to PyWPS. I confirm that my contributions to PyWPS will be compatible with the PyWPS license guidelines at the time of contribution.
  • I have already previously agreed to the PyWPS Contributions and Licensing Guidelines

@gschwind gschwind force-pushed the pywps-4.4-007 branch 2 times, most recently from cf3b806 to 9f0ee7f Compare April 25, 2021 12:51
@cehbrecht cehbrecht requested a review from huard April 26, 2021 13:45
Copy link
Collaborator

@huard huard left a comment

Choose a reason for hiding this comment

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

Made some proposals to fix failing tests here: gschwind#1

Otherwise this looks good and makes the code clearer I believe.

Comment on lines 360 to 376
@prop.setter
def prop(self, value):
LOGGER.warning("Deprecated use of IOHandler.prop, prefer self.value = self.value")
if value == "file":
self._iohandler = FileHandler(self._iohandler.file, self)
elif value == "data":
self._iohandler = DataHandler(self._iohandler.data, self)
elif value == "stream":
self._iohandler = StreamHandler(self._iohandler.stream, self)
elif value == "url":
self._iohandler = UrlHandler(self._iohandler.url, self)
Copy link
Collaborator

Choose a reason for hiding this comment

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

Do we really need this ? Removing it does not create any test failure. I don't think this was supported previously.

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Hello huard,

At beginning I did not implement the prop setter but the test : test_inout.py:test_complex_input_stream need it.

Otherwise, I agree that we should remove it.

@huard
Copy link
Collaborator

huard commented Apr 26, 2021

I've tested this with emu + birdy and I'm getting 3 INTERNAL SERVER ERRORS.

https://github.com/bird-house/emu
https://github.com/bird-house/birdy

To reproduce:

  1. Install emu and launch it with emu start
  2. Install birdy and run the test suite with pytest

@gschwind
Copy link
Collaborator Author

Hello huart,

I will have a look, best regards.

@coveralls
Copy link

coveralls commented Apr 27, 2021

Coverage Status

Coverage remained the same at 0.0% when pulling babc8fc on gschwind:pywps-4.4-007 into 559f13b on geopython:pywps-4.4.

@gschwind
Copy link
Collaborator Author

Hello huard,

I found the guilty :)

Thank you for your feedbacks

Best regards

gschwind and others added 5 commits April 28, 2021 20:10
The current implementation use a tricks that manipulate the __mro__.
This trick do not have any obvious benefit and make the code much more
complicated than necessary. This patch simplifier the implementation by
replacing the tricky class change to a change in mamber's variable.
@cehbrecht cehbrecht merged commit 343d825 into geopython:pywps-4.4 May 6, 2021
@cehbrecht
Copy link
Collaborator

@gschwind @huard merged . Thanks :)

@huard
Copy link
Collaborator

huard commented May 12, 2022

Hi @gschwind

I'm working on parallelism in PyWPS and I'm hitting an issue with the serialization of Process instances. The IO handlers include weakrefs that are not picklable, and so I'm not able to send processes to "workers". Could we replace those weakref by something else that would be pickable?

@gschwind
Copy link
Collaborator Author

Hello huard,

Why you do not use json serialization as it's done currently to store request in data base ?

Best regards.

@huard
Copy link
Collaborator

huard commented May 13, 2022

I tried to add __setstate__ and getstatemethod using thejsonproperty andfrom_json` method, but it broke pickling. Replacing the weakrefs by normal references solved this issue, but I wanted to know what were the downsides. I might be missing something obvious. I'll open a separate issue about PyWPS object serialization.

@gschwind
Copy link
Collaborator Author

I guess there is downside, I don't think I use weakref if there is no need of it. I have to check. The two main reason to use it. One is for breaking circular dependency with object references such as A->B->A that cause memory leak and require garbage collector to fix it. Second is to not take the ownership of the variableand being able to check if the owner destroyed it (released it).

I have to check. In other hand I would not use pickle to transfer python object from one process to another, but I do not know your use case.

Best regards.

@huard
Copy link
Collaborator

huard commented May 13, 2022

Ok thanks, see #658.

@gschwind
Copy link
Collaborator Author

gschwind commented May 14, 2022

Hello,

After a quick check, it is for breaking circular references. for instance within the code IOHandler._iohandler is a refecence to FileHandler or DataHandler and those object has FileHandler._ref and DataHandler._ref that is linked to there owner IOHandler. If I do not use weakref here I have a reference loop where IOHandler own FileHandler or DataHandler, and those FileHandler or DataHandler own their parent IOHandler.

If you want as dirty fix, you can use prepare_serialization that remove the weak ref with None and fix_deserialize that rebuild the weak_ref. like:

def prepare_serialization(self):
   self._iohandler._ref = None

def fix_deserialize(self):
    self._iohandler._ref = weakref.ref(self)

Best regards

@huard
Copy link
Collaborator

huard commented May 16, 2022

Many thanks for the explanation and suggestion.

@gschwind gschwind deleted the pywps-4.4-007 branch July 20, 2022 08:50
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.

4 participants