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

GetJobsPayload & JobSelectionBehaviour #108

Closed
Karrenbelt opened this issue Sep 3, 2022 · 1 comment
Closed

GetJobsPayload & JobSelectionBehaviour #108

Karrenbelt opened this issue Sep 3, 2022 · 1 comment

Comments

@Karrenbelt
Copy link
Contributor

Karrenbelt commented Sep 3, 2022

The content of this payload is job_list: List[str] and it's property casts to string job_list(self) -> str. This was for done out of convenience since lists are not serializable at the moment. However, the __init__ and property return should be of the same type

class GetJobsPayload(BaseKeep3rJobPayload):
"""GetJobsPayload"""
_data_keys: Tuple[str] = ("job_list",)
transaction_type = TransactionType.JOB_LIST
def __init__(self, sender: str, job_list: List[str], **kwargs: Any) -> None:
"""Initialize an 'get_jobs' transaction payload.
:param sender: the sender (Ethereum) address
:param job_list: The job list
:param kwargs: the keyword arguments
"""
super().__init__(sender, **kwargs)
self._job_list = job_list
@property
def job_list(self) -> str:
"""Get the job list."""
return "".join(self._job_list)

This can easily lead to issues, such as here:

  1. selection behaviour treating it as List[str] still

    class JobSelectionBehaviour(Keep3rJobBaseBehaviour):
    """JobSelectionBehaviour"""
    behaviour_id: str = "job_selection"
    matching_round: Type[AbstractRound] = JobSelectionRound
    def async_act(self) -> Generator:
    """
    Behaviour to get whether job is selected.
    job selection payload is shared between participants.
    """
    with self.context.benchmark_tool.measure(self.behaviour_id).local():
    if not self.synchronized_data.job_list:
    current_job = None
    else:
    addresses = self.synchronized_data.job_list
    period_count = self.synchronized_data.period_count
    job_ix = period_count % len(addresses)
    current_job = addresses[job_ix]
    payload = JobSelectionPayload(self.context.agent_address, current_job)
    self.context.logger.info(f"Job contract selected: {current_job}")
    with self.context.benchmark_tool.measure(self.behaviour_id).consensus():
    yield from self.send_a2a_transaction(payload)
    yield from self.wait_until_round_end()
    self.set_done()

  2. IsWorkableRound updating the shared state changes what was originally a List[str] into a str when not workable

    # remove the non-workable job, then transition to JobSelectionRound
    current_job = cast(str, self.synchronized_data.current_job)
    job_list = self.synchronized_data.job_list.replace(current_job, "")
    state = self.synchronized_data.update(job_list=job_list)
    return state, Event.NOT_WORKABLE

Note that - in case of WORKABLE and NOT_PROFITABLE the job should also be removed from the list. It is probably smarter to:

  • set current_job to an empty string or None in GetJobsRound (and set job_list as we do now)
  • remove a job from the list when selecting it first during JobSelection, which should lead to a situation where the current_job is never among the job_list

P.S.
leaving a reference to this comment to be addressed as well: #106 (comment)

@0xArdi
Copy link
Collaborator

0xArdi commented Mar 9, 2023

This has been resolved.

@0xArdi 0xArdi closed this as completed Mar 9, 2023
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

No branches or pull requests

2 participants