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

Implemented support for adding snapshot to a profile #9

Merged
merged 1 commit into from
Oct 19, 2024

Conversation

petrknap
Copy link
Owner

@petrknap petrknap commented Oct 15, 2024

  • This pull request does not contain any breaking change
  • I asked the AI to briefly summarize, use and improve this changes, and I'm okay with the output:

Could you briefly summarize the following code for me?

abstract class Profiling {
    private readonly Profile $profile;
    abstract public static function start(): self;
    /**
     * @throws Exception\ProfilingHasBeenAlreadyFinished
     */
    public function snapshot(): void {
       $this->checkProfileState();

       $this->profile->tickHandler();
    }
    /**
     * @throws Exception\ProfilingHasBeenAlreadyFinished
     */
    abstract public function finish(): ProfileInterface;
    /**
     * @throws Exception\ProfilingHasBeenAlreadyFinished
     */
    private function checkProfileState(): void
    {
        if ($this->profile->getState() === ProfileState::Finished) {
            throw new Exception\ProfilingHasBeenAlreadyFinished();
        }
    }
}
abstract class Profile implements ProfileInterface {}

Sure thing.

  • Profiling is an abstract class with a private, readonly $profile property of type Profile.
  • It has an abstract static method start() that returns an instance of itself.
  • It includes a snapshot() method to take a snapshot, which ensures profiling hasn't already finished by calling checkProfileState(). This method throws an exception if profiling has already finished.
  • The finish() method is abstract and is meant to return a ProfileInterface.
  • The private checkProfileState() method checks the profile state and throws an exception if profiling has finished.

Additionally, Profile is an abstract class that implements ProfileInterface.

Clear as a crystal?

Could you show me how to use it?

Sure thing. Here’s a basic example demonstrating how to use the abstract Profiling class and the Profile class.

First, you’ll need concrete implementations of these abstract classes. Here’s a complete example:

// Assuming necessary classes and interfaces are defined as discussed
abstract class Profiling {
    private readonly Profile $profile;

    abstract public static function start(): self;

    /**
     * @throws Exception\ProfilingHasBeenAlreadyFinished
     */
    public function snapshot(): void {
        $this->checkProfileState();
        $this->profile->tickHandler();
    }

    /**
     * @throws Exception\ProfilingHasBeenAlreadyFinished
     */
    abstract public function finish(): ProfileInterface;

    /**
     * @throws Exception\ProfilingHasBeenAlreadyFinished
     */
    private function checkProfileState(): void {
        if ($this->profile->getState() === ProfileState::Finished) {
            throw new Exception\ProfilingHasBeenAlreadyFinished();
        }
    }
}

abstract class Profile implements ProfileInterface {}

class MyProfiling extends Profiling {
    public static function start(): self {
        $instance = new self();
        // Initialize profile here
        return $instance;
    }

    public function finish(): ProfileInterface {
        // Finalize and return profile
        return new MyProfile();
    }
}

class MyProfile extends Profile {
    public function getDuration(): float {
        // Return the duration or other profiling metrics
    }
}

// Using the profiling
try {
    $profiling = MyProfiling::start();
    // Code you want to profile
    $profiling->snapshot();
    // More code you want to profile
    $profile = $profiling->finish();
    echo "Profiling finished successfully.";
} catch (Exception\ProfilingHasBeenAlreadyFinished $e) {
    echo "Profiling has already been finished.";
}

This example covers:

  1. Starting the profiling with MyProfiling::start().
  2. Taking a snapshot during the profiling process with $profiling->snapshot().
  3. Finishing the profiling with $profiling->finish() to get the profile data.

This should give you a good starting point for using the Profiling and Profile classes. Happy coding! 🚀

Is there any way to do it better?

Definitely, let’s refine it.

  1. Use Dependency Injection: Instead of having the Profile dependency directly in the Profiling class, inject it. It makes the code more flexible and testable.
  2. Separate Concerns: Separate the profiling logic from the application logic as much as possible.
  3. Improve Exception Handling: Centralize exception handling to maintain cleaner code.

Here’s an enhanced version:

abstract class Profiling {
    private Profile $profile;

    public function __construct(Profile $profile) {
        $this->profile = $profile;
    }

    abstract public static function start(Profile $profile): self;

    /**
     * @throws Exception\ProfilingHasBeenAlreadyFinished
     */
    public function snapshot(): void {
        $this->checkProfileState();
        $this->profile->tickHandler();
    }

    /**
     * @throws Exception\ProfilingHasBeenAlreadyFinished
     */
    abstract public function finish(): ProfileInterface;

    /**
     * @throws Exception\ProfilingHasBeenAlreadyFinished
     */
    private function checkProfileState(): void {
        if ($this->profile->getState() === ProfileState::Finished) {
            throw new Exception\ProfilingHasBeenAlreadyFinished();
        }
    }
}

abstract class Profile implements ProfileInterface {}

// Concrete Profiling Implementation
class MyProfiling extends Profiling {
    public static function start(Profile $profile): self {
        return new self($profile);
    }

    public function finish(): ProfileInterface {
        // Finalize and return profile
        return new MyProfile();
    }
}

// Concrete Profile Implementation
class MyProfile extends Profile {
    public function getDuration(): float {
        // Return the duration or other profiling metrics
    }
}

// Using the profiling
try {
    $profile = new MyProfile();
    $profiling = MyProfiling::start($profile);
    // Code you want to profile
    $profiling->snapshot();
    // More code you want to profile
    $profile = $profiling->finish();
    echo "Profiling finished successfully.";
} catch (Exception\ProfilingHasBeenAlreadyFinished $e) {
    echo "Profiling has already been finished.";
}

This version provides cleaner code through dependency injection and better exception handling, enhancing both flexibility and readability. Give it a spin and see how it feels! 🚀 Do you have other pieces of code that need a touch-up?

@petrknap petrknap force-pushed the touchable-profiling branch 2 times, most recently from 004e552 to f4dffc7 Compare October 15, 2024 18:36
@petrknap petrknap changed the title Implemented support for touching profiling Implemented support of profile touching Oct 15, 2024
@petrknap petrknap marked this pull request as ready for review October 15, 2024 18:56
@petrknap
Copy link
Owner Author

Based on hints from AI Copilot the feature could be renamed from touch to snapshot.

@petrknap petrknap merged commit 493c1c0 into main Oct 19, 2024
2 checks passed
@petrknap petrknap changed the title Implemented support of profile touching Implemented support for adding snapshot to a profile Oct 19, 2024
@petrknap petrknap deleted the touchable-profiling branch October 19, 2024 12:00
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.

1 participant