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

Implement watch_file and watch_repository #14

Closed
wants to merge 16 commits into from
Closed

Implement watch_file and watch_repository #14

wants to merge 16 commits into from

Conversation

ikhoon
Copy link
Contributor

@ikhoon ikhoon commented Oct 27, 2021

Motivation:

The watch APIs implemented in upstream's client are the most loved features by users.
Python users also want to use the API in this Python client too.

Modifications:

  • Implement file_watcher and repository_watcher
  • Apply exception handler
  • Update docstring

Result:

You can watch the changes in a repository using the watch APIs.

TODO:
- [ ] Implement `file_watcher` and `repository_watcher`
- [ ] Apply exception handler
- [ ] Update docstring
@ikhoon ikhoon added this to the 0.1.0 milestone Oct 30, 2021
@ikhoon ikhoon marked this pull request as ready for review November 2, 2021 07:35
@hexoul hexoul requested review from hexoul and minwoox November 5, 2021 08:20
centraldogma/content_service.py Show resolved Hide resolved
centraldogma/content_service.py Show resolved Hide resolved
centraldogma/content_service.py Outdated Show resolved Hide resolved
else:
self._state = WatchState.STARTED

# FIXME(ikhoon): Replace Thread with Coroutine of asyncio once AsyncClient is implemented.
Copy link
Member

Choose a reason for hiding this comment

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

Are we going to do this before we release 0.1.0?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

That seems to depend on how we are going to implement AsyncClient.
If it makes huge breaking changes, it would be better to do it in 0.1.0.

Copy link
Collaborator

Choose a reason for hiding this comment

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

Did you consider asyncio for watcher behind concurrent future? As httpx supports asyncio, using only asyncio without concurrent future may be good in the light of consistency. However, we can even mix them if there are pros. What is the background that concurrent future is chosen over asyncio to implement the watcher in this PR? Multi-threading is well suited for Central Dogma than event loop?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Good question. First, I tried to use Future in asyncio and realized that there is no operation that waits for a result of Future like future.result().
If users need an initial value when starting an application, the blocking operation would be helpful to initialize the application. Even though we change the internal implementation of Watcher, I think, we still use the API of Watcher

Copy link
Collaborator

Choose a reason for hiding this comment

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

there is no operation that waits for a result of Future like future.result().

I couldn't understand this part. There is await reserved keyword. Did I get wrong point? https://docs.python.org/3/library/asyncio-task.html

Copy link
Collaborator

@hexoul hexoul left a comment

Choose a reason for hiding this comment

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

Sorry for late review. 🥲
I left partial comments now and will add if I have time.

centraldogma/base_client.py Outdated Show resolved Hide resolved
centraldogma/repository_watcher.py Outdated Show resolved Hide resolved
centraldogma/repository_watcher.py Outdated Show resolved Hide resolved
centraldogma/data/entry.py Outdated Show resolved Hide resolved
centraldogma/util.py Outdated Show resolved Hide resolved
centraldogma/data/entry.py Show resolved Hide resolved
centraldogma/query.py Outdated Show resolved Hide resolved
centraldogma/content_service.py Outdated Show resolved Hide resolved
centraldogma/query.py Outdated Show resolved Hide resolved
return Entry.text(revision, entry_path, content)
elif query_type == QueryType.IDENTITY_JSON or query_type == QueryType.JSON_PATH:
if received_entry_type != EntryType.JSON:
raise CentralDogmaException(
Copy link
Collaborator

Choose a reason for hiding this comment

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

Would it be better to use server-side exception indicating 500, INTERNAL_SERVER_ERROR instead of CentralDogmaException?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

This method is invoked when 200 OK is received. It makes no sense to use 500 INTERNAL_SERVER_ERROR.

Copy link
Collaborator

@hexoul hexoul Nov 18, 2021

Choose a reason for hiding this comment

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

But it can be caused by server's abnormal behavior? Hmm then how about UnknownException?

Copy link
Contributor Author

@ikhoon ikhoon Nov 19, 2021

Choose a reason for hiding this comment

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

My test code did not fully cover this case.
Added a new test case for this. 893aac5 (#14)

Copy link
Collaborator

Choose a reason for hiding this comment

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

Thanks. WDYT about UnknownException?

centraldogma/content_service.py Outdated Show resolved Hide resolved
centraldogma/data/entry.py Show resolved Hide resolved
tests/integration/test_watcher.py Outdated Show resolved Hide resolved
@@ -182,3 +192,114 @@ def push(
the content is supposed to be the new name.
"""
return self.content_service.push(project_name, repo_name, commit, changes)

def watch_repository(
Copy link
Collaborator

Choose a reason for hiding this comment

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

Could you add unit tests for new features? Only integration tests were added.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

By the way, I don't get a strong advantage of the unit tests. The call path and coverage are rather similar. Is it better to verify Dogma with integration tests and add unit tests for other smaller units? What do you think? 🤔

Copy link
Collaborator

Choose a reason for hiding this comment

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

I understand your stand. Of course, integration tests already cover all. I just would like to improve

  1. consistency as existing functions have both unit test and integration test.
  2. If changed by other developer, they can know in the early stage before integration test.
  3. If it has complex logic in the future, white box testing seems to be needed rather than black box testing.

However, these three points have no strong advantage as you said. Then we are able to keep going without unit test and making the unit test if needed?

Copy link
Member

Choose a reason for hiding this comment

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

Thanks for the good suggestion. 😉
I believe that it's okay without unit tests if the integration tests cover the logic of the changes.

Then we are able to keep going without unit test and making the unit test if needed?

Yeah, I think it's the way to go. 😄

tests/integration/test_watcher.py Outdated Show resolved Hide resolved
centraldogma/watcher.py Show resolved Hide resolved
else:
self._state = WatchState.STARTED

# FIXME(ikhoon): Replace Thread with Coroutine of asyncio once AsyncClient is implemented.
Copy link
Collaborator

Choose a reason for hiding this comment

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

Did you consider asyncio for watcher behind concurrent future? As httpx supports asyncio, using only asyncio without concurrent future may be good in the light of consistency. However, we can even mix them if there are pros. What is the background that concurrent future is chosen over asyncio to implement the watcher in this PR? Multi-threading is well suited for Central Dogma than event loop?

@ikhoon
Copy link
Contributor Author

ikhoon commented Nov 19, 2021

By the way, why GitHub Actions is not working even though master branch is merged. 🤔

@ikhoon ikhoon closed this Nov 19, 2021
@ikhoon ikhoon reopened this Nov 19, 2021
@ikhoon ikhoon closed this Nov 19, 2021
@ikhoon ikhoon reopened this Nov 19, 2021
@ikhoon
Copy link
Contributor Author

ikhoon commented Nov 19, 2021

By the way, why GitHub Actions is not working even though master branch is merged. 🤔

https://github.community/t/github-action-action-in-private-repository/16063
We can't trigger GitHub Actions with a PR on the cross repositories. 😅
Is it time to make this public with a "work in progress" badge? I think it is good to share the developing progress with others.
@syleeeee Any thoughts on this? If you want to open a complete product, I can run a test manually at the moment.

@syleeeee
Copy link
Member

@ikhoon Sounds good to me. We could add the repository description as WIP after making it public.
Then I'll announce the news on Twitter later when it's all ready :)

@ikhoon
Copy link
Contributor Author

ikhoon commented Nov 19, 2021

Thanks for the confirmation. I will update the notice into the README and turn this repository into public.
/cc @hexoul @minwoox

@ikhoon ikhoon closed this Nov 22, 2021
@ikhoon
Copy link
Contributor Author

ikhoon commented Nov 22, 2021

Hmm... reopen button disappeared. 😅

@ikhoon
Copy link
Contributor Author

ikhoon commented Nov 22, 2021

The relationship between downstream and upstream is disconnected.
Let me refork this repository and reopen a PR.

@hexoul hexoul removed this from the 0.1.1 milestone Jul 27, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

4 participants