Question: The second part of this workshop upgrades your solution using the observer pattern to handle when a job is complete or encounters an error during
The second part of this workshop upgrades your solution using the observer pattern to handle when a job is complete or encounters an error during processing.
- Processor (to be updated)
- CentralUnit (to be updated)
- w5 (partially supplied)
Processor Module
Update the Processor module to run it like a functor and register callbacks to execute in specific cases.
Private Data
- a data member that stores the address of a function that will be run when a job finishes processing. The function returns nothing and takes a hosting central unit by reference as its first argument and the address of a processor as its second argument.
- an std::function object that targets a function to be run when an error occurs. The function targetted returns nothing and takes the address of a processor as its only argument.
Public Members
- on_complete(): takes the address of a callback function to register and run when a job finishes processing as an argument and sets the respective instance member. This function returns nothing.
- on_error(): takes, as an argument, an std::function callback to register and run when a job encounters an error during processing and sets the respective instance member. This function returns nothing.
- an operator overload to make a Processor a functor. This function runs the processor once, similar to run(). If the job assigned to the processor was already completed, do nothing. If the assigned job is completed after performing m_power units of work on it, this function calls the appropriate callback registered, if any. If the job reports an std::underflow_error, handle it by calling the registered error callback, if any.
- free(): makes the processor available by unassigning the current job (do not clear any memory allocated for it) and returning the address of the job that was unassigned.
Friend Helpers
- std::ostream& operator<<(std::ostream&, const Processor&): inserts the details about this processor into the output stream in the following format:
(POWER) BRAND CODE processing CURRENT_JOB_DETAILS - if the processor is not assigned a job, only print out the power, brand, and code.
CentralUnit Module
Update the CentralUnit module to handle a job completion and error.
Public members
complete_job(): a class member function that receives a central unit (by reference) and the address of a type T unit as its arguments. This function frees the unit received and clears memory allocated for the job that was assigned to that unit. This function also logs the following:
[COMPLETE] JOB_DETAILS using UNIT_DETAILS AVAILABLE_UNITS units available. use the insertion operator to log the JOB_DETAILS and UNIT_DETAILS.
custom constructor (to be updated): update your custom constructor to register callbacks with units. For each unit created:
- register the class member function complete_job() as a callback for a job completion with the unit.
- register a lambda function that will make the unit received as as argument available and clears memory allocated for the job that was assigned to that unit. The lambda also uses the error logging object to log the following:
Failed to complete job JOB_NAME AVAILABLE_UNITS units available - where JOB_NAME is the name of the job with the error and AVAILABLE_UNITS is the number of available units in this central unit.
run() (to be updated): Update the run() function to run the unit by using it as a functor instead of calling the unit's run() function.
operator+=(): receives the address of a unit (takes ownership) and adds it to the central unit (resize the data member if needed). Assign the necessary job error and completion callbacks (similar to above) to this newly added unit. If the unit received is not available, this function does not add it and reports an exception instead.
operator[](): a query that receives the title of a job as a C-style null-terminated string and returns a pointer to the unit that is currently assigned a job that matches the given title. If no unit is assigned a matching job, this function reports an std::out_of_range error with the message Job is not being handled by a unit. This query does not modify the state of the central unit.
display(): a query that receives and returns nothing and displays the central unit's current state. Logs Central TYPE Unit list as a heading (TYPE is the type of work being done by the central unit). Then logs each individual unit on a separate line in the following format:
[XXXX] UNIT_DETAILS where XXXX is the unit's index (starting from 1) in the central unit and is zero-padded.
This query does not modify the state of the central unit.
Step by Step Solution
There are 3 Steps involved in it
Get step-by-step solutions from verified subject matter experts
