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

Function and jobs refactor - resolve circular dependencies #1517

Merged
merged 33 commits into from
Oct 28, 2024

Conversation

korgan00
Copy link
Collaborator

@korgan00 korgan00 commented Oct 15, 2024

Summary

Depends on #1513

Details and comments

To resolve the circular dependencies, QiskitFunction and Job defines an interface (pure abstract class in python) with their needs: RunService and JobService. The old client: Any variable will be replaced with _run_service: RunService and _job_service: JobService. The BaseClient should implement this interfaces.
We are achieving multiple objectives:

  1. QiskitFunction and Job doesn't need to import BaseClient, the imports are in the BaseClient side.
  2. _run_service and _job_service variables now can be resolved by the IDE and offer autocompletion and type-checking of the linter and code-quality tools.
  3. QiskitFunction and Job are decoupled.
  4. This also improves the Interface Segregation part of the S.O.L.I.D principles.

Additionally:
QiskitFunction had the run method that raised an exception by default if you create it and it worked when it is retrieved from the client.
The QiskitFunction no longer has a run method because it doesn't work without a client. RunnableQiskitFunction inherits from it, implements the run and receives the client as a not optional run_service. This is less error prone.
Client's upload, function and functions now return RunnableQiskitFunction by default.

# Conflicts:
#	client/qiskit_serverless/core/client.py
#	client/qiskit_serverless/core/clients/local_client.py
#	client/qiskit_serverless/core/clients/ray_client.py
#	client/qiskit_serverless/core/clients/serverless_client.py
# Conflicts:
#	client/qiskit_serverless/core/client.py
#	client/qiskit_serverless/core/clients/local_client.py
#	client/qiskit_serverless/core/clients/ray_client.py
#	client/qiskit_serverless/core/clients/serverless_client.py
#	client/qiskit_serverless/core/files.py
#	client/qiskit_serverless/core/function.py
#	client/qiskit_serverless/core/job.py
Comment on lines -143 to -191
@abstractmethod
def run(
self,
program: Union[QiskitFunction, str],
arguments: Optional[Dict[str, Any]] = None,
config: Optional[Configuration] = None,
) -> Job:
"""Execute a program as a async job.

Example:
>>> serverless = QiskitServerless()
>>> program = QiskitFunction(
>>> "job.py",
>>> arguments={"arg1": "val1"},
>>> dependencies=["requests"]
>>> )
>>> job = serverless.run(program)
>>> # <Job | ...>

Args:
arguments: arguments to run program with
program: Program object

Returns:
Job
"""

@abstractmethod
def status(self, job_id: str) -> str:
"""Check status."""

@abstractmethod
def stop(
self, job_id: str, service: Optional[QiskitRuntimeService] = None
) -> Union[str, bool]:
"""Stops job/program."""

@abstractmethod
def result(self, job_id: str) -> Any:
"""Return results."""

@abstractmethod
def logs(self, job_id: str) -> str:
"""Return logs."""

@abstractmethod
def filtered_logs(self, job_id: str, **kwargs) -> str:
"""Return filtered logs."""

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

This methods are defined in new RunService and JobClient abstract classes.

@korgan00 korgan00 marked this pull request as ready for review October 22, 2024 17:06
@@ -76,13 +77,44 @@ class Configuration: # pylint: disable=too-many-instance-attributes
auto_scaling: Optional[bool] = False


class JobClient(ABC):
Copy link
Member

Choose a reason for hiding this comment

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

As we commented through a call JobClient I would like to rename it to JobService to match it with the current RunService.

Apart from that I saw everything good, really good job here @korgan00

@Tansito
Copy link
Member

Tansito commented Oct 23, 2024

@IceKhan13 if you can take a look to this PR too and give some feedback to @korgan00 it would be nice!

Copy link
Collaborator

@paaragon paaragon left a comment

Choose a reason for hiding this comment

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

Very good job @korgan00 😄

I have a question regarding function.py and job.py.

  • job.py contains three classes: Configuration, JobService and Job
  • function.py contains another three classes: QiskitFunction, RunService and RunnableQiskitFunction.

Would it make sense to have some of these classes in a separated file? I was thinking that maybe RunService and JobService could be in another file

version: version of a program
"""

_run_service: RunService = None
Copy link
Collaborator

Choose a reason for hiding this comment

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

Suggested change
_run_service: RunService = None
_run_service: Optional[RunService] = None

Copy link
Collaborator Author

@korgan00 korgan00 Oct 24, 2024

Choose a reason for hiding this comment

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

In this case i think it shouldnt be optional because, to be runnable it needs an associated run service. If run_service is None, then it is just a QiskitFunction

@korgan00
Copy link
Collaborator Author

Very good job @korgan00 😄

I have a question regarding function.py and job.py.

  • job.py contains three classes: Configuration, JobService and Job
  • function.py contains another three classes: QiskitFunction, RunService and RunnableQiskitFunction.

Would it make sense to have some of these classes in a separated file? I was thinking that maybe RunService and JobService could be in another file

Since they are very coupled to that files, I added it to the same file, but im ok with splitting it. What do you think @IceKhan13 , @Tansito ?

Copy link
Member

@IceKhan13 IceKhan13 left a comment

Choose a reason for hiding this comment

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

woohoo, circular deps gone!
LGTM
THank you!

@Tansito
Copy link
Member

Tansito commented Oct 28, 2024

I think by now having them in the same file is good enough, as we commented we are not expecting to re use them in other places in the near future, @korgan00 👍

@Tansito Tansito self-requested a review October 28, 2024 16:17
@korgan00 korgan00 merged commit c3b8446 into main Oct 28, 2024
10 checks passed
@Tansito Tansito deleted the function-and-jobs-refactor branch October 28, 2024 16:38
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