Skip to content

Владимир Бессонов P3312 #141

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

Closed
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
170 changes: 155 additions & 15 deletions tools/actor_model/actors.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@

static auto ShouldContinue = std::make_shared<TProgramShouldContinue>();

class TMaxPrimeDivisorActor;

/*
Вам нужно написать реализацию TReadActor, TMaximumPrimeDevisorActor, TWriteActor
*/
Expand Down Expand Up @@ -39,6 +41,53 @@ TReadActor
*/

// TODO: напишите реализацию TReadActor
class TReadActor : public NActors::TActorBootstrapped<TReadActor> {
const NActors::TActorId m_WriterActorId;
size_t m_ActiveWorkersCount = 0;
bool m_InputFinished = false;

public:
TReadActor(NActors::TActorId writerActorId)
: m_WriterActorId(writerActorId)
{}

void Bootstrap() {
Become(&TReadActor::StateFunc);
Send(SelfId(), new NActors::TEvents::TEvWakeup());
}

private:
STRICT_STFUNC(StateFunc, {
cFunc(NActors::TEvents::TEvWakeup::EventType, HandleWakeup);
cFunc(TEvents::EvDone, HandleWorkerDone);
});

void HandleWakeup() {
int64_t inputNumber;
if (std::cin >> inputNumber) {
m_ActiveWorkersCount++;
Register(CreateMaxPrimeDivisorActor(inputNumber, SelfId(), m_WriterActorId).Release());
Send(SelfId(), new NActors::TEvents::TEvWakeup());
} else {
m_InputFinished = true;
if (m_ActiveWorkersCount == 0) {
Shutdown();
}
}
}

void HandleWorkerDone() {
m_ActiveWorkersCount--;
if (m_InputFinished && m_ActiveWorkersCount == 0) {
Shutdown();
}
}

void Shutdown() {
Send(m_WriterActorId, new NActors::TEvents::TEvPoisonPill());
PassAway();
}
};

/*
Требования к TMaximumPrimeDevisorActor:
Expand Down Expand Up @@ -68,7 +117,69 @@ TMaximumPrimeDevisorActor
PassAway()
*/

int64_t FindLargestPrimeDivisor(int64_t number) {
if (number <= 1) {
return 1;
}

int64_t largestPrime = -1;

// Handle even numbers
while (number % 2 == 0) {
largestPrime = 2;
number /= 2;
}

// Check odd divisors up to sqrt(n)
for (int64_t divisor = 3; divisor * divisor <= number; divisor += 2) {
while (number % divisor == 0) {
largestPrime = divisor;
number /= divisor;
}
}

// If remaining number is prime
if (number > 1) {
largestPrime = number;
}

return largestPrime != -1 ? largestPrime : 1;
}

// TODO: напишите реализацию TMaximumPrimeDevisorActor
class TMaxPrimeDivisorActor : public NActors::TActorBootstrapped<TMaxPrimeDivisorActor> {
const int64_t m_InputNumber;
const NActors::TActorId m_ReaderActorId;
const NActors::TActorId m_WriterActorId;

public:
TMaxPrimeDivisorActor(int64_t number,
NActors::TActorId readerActorId,
NActors::TActorId writerActorId)
: m_InputNumber(number)
, m_ReaderActorId(readerActorId)
, m_WriterActorId(writerActorId)
{}

void Bootstrap() {
ProcessAndRespond();
}

private:
void ProcessAndRespond() {
int64_t result = FindLargestPrimeDivisor(m_InputNumber);

Send(m_WriterActorId, new TEvents::TEvWriteValueRequest(result));
Send(m_ReaderActorId, new TEvents::TEvDone());
PassAway();
}
};

THolder<NActors::IActor> CreateMaxPrimeDivisorActor(int64_t value,
NActors::TActorId readerActorId,
NActors::TActorId writerActorId) {
return MakeHolder<TMaxPrimeDivisorActor>(value, readerActorId, writerActorId);
}

/*
Требования к TWriteActor:
Expand All @@ -88,39 +199,68 @@ TWriteActor
*/

// TODO: напишите реализацию TWriteActor
class TWriteActor : public NActors::TActor<TWriteActor> {
int64_t m_ResultSum = 0;

class TSelfPingActor : public NActors::TActorBootstrapped<TSelfPingActor> {
TDuration Latency;
TInstant LastTime;
public:
TWriteActor() : TActor(&TWriteActor::StateFunc) {}

STRICT_STFUNC(StateFunc, {
hFunc(TEvents::TEvWriteValueRequest, HandleResult);
cFunc(NActors::TEvents::TEvPoisonPill::EventType, HandleShutdown);
});

void HandleResult(TEvents::TEvWriteValueRequest::TPtr& event) {
m_ResultSum += event->Get()->Value;
}

void HandleShutdown() {
std::cout << m_ResultSum << std::endl;
ShouldContinue->ShouldStop();
PassAway();
}
};

class TSystemMonitorActor : public NActors::TActorBootstrapped<TSystemMonitorActor> {
TDuration m_MaxAllowedLatency;
TInstant m_LastPingTime;

public:
TSelfPingActor(const TDuration& latency)
: Latency(latency)
TSystemMonitorActor(const TDuration& maxLatency)
: m_MaxAllowedLatency(maxLatency)
{}

void Bootstrap() {
LastTime = TInstant::Now();
Become(&TSelfPingActor::StateFunc);
m_LastPingTime = TInstant::Now();
Become(&TSystemMonitorActor::StateFunc);
Send(SelfId(), std::make_unique<NActors::TEvents::TEvWakeup>());
}

STRICT_STFUNC(StateFunc, {
cFunc(NActors::TEvents::TEvWakeup::EventType, HandleWakeup);
cFunc(NActors::TEvents::TEvWakeup::EventType, HandlePing);
});

void HandleWakeup() {
auto now = TInstant::Now();
TDuration delta = now - LastTime;
Y_VERIFY(delta <= Latency, "Latency too big");
LastTime = now;
void HandlePing() {
auto currentTime = TInstant::Now();
TDuration actualLatency = currentTime - m_LastPingTime;
Y_VERIFY(actualLatency <= m_MaxAllowedLatency, "System latency exceeded allowed maximum");
m_LastPingTime = currentTime;
Send(SelfId(), std::make_unique<NActors::TEvents::TEvWakeup>());
}
};

THolder<NActors::IActor> CreateSelfPingActor(const TDuration& latency) {
return MakeHolder<TSelfPingActor>(latency);
THolder<NActors::IActor> CreateSystemMonitorActor(const TDuration& latency) {
return MakeHolder<TSystemMonitorActor>(latency);
}

std::shared_ptr<TProgramShouldContinue> GetProgramShouldContinue() {
return ShouldContinue;
}

THolder<NActors::IActor> CreateReadActor(NActors::TActorId writerActorId) {
return MakeHolder<TReadActor>(writerActorId);
}

THolder<NActors::IActor> CreateWriteActor() {
return MakeHolder<TWriteActor>();
}
8 changes: 7 additions & 1 deletion tools/actor_model/actors.h
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,12 @@
#include <util/generic/ptr.h>
#include <library/cpp/actors/util/should_continue.h>

THolder<NActors::IActor> CreateSelfPingActor(const TDuration& latency);
#include "events.h"

THolder<NActors::IActor> CreateReadActor(NActors::TActorId writerActorId);
THolder<NActors::IActor> CreateWriteActor();
THolder<NActors::IActor> CreateMaxPrimeDivisorActor(int64_t value, NActors::TActorId readerActorId, NActors::TActorId writerActorId);

THolder<NActors::IActor> CreateSystemMonitorActor(const TDuration& latency);

std::shared_ptr<TProgramShouldContinue> GetProgramShouldContinue();
21 changes: 20 additions & 1 deletion tools/actor_model/events.h
Original file line number Diff line number Diff line change
@@ -1,6 +1,25 @@
#pragma once

#include <library/cpp/actors/core/event_local.h>
#include <library/cpp/actors/core/events.h>
#include <library/cpp/actors/core/actorid.h>

struct TEvents {
// Вам нужно самостоятельно сюда добавить все необходимые events в NActors::TEvents::ES_PRIVATE
enum EEv : ui32 {
EvBegin = NActors::TEvents::ES_PRIVATE,

EvWriteValueRequest = EvBegin + 1,
EvDone,

EvEnd
};

static_assert(EvEnd < NActors::TEvents::ES_PRIVATE + 1024, "Too many private events");

struct TEvWriteValueRequest : NActors::TEventLocal<TEvWriteValueRequest, EvWriteValueRequest> {
int64_t Value;

TEvWriteValueRequest(int64_t value) : Value(value) {}
};
struct TEvDone : NActors::TEventLocal<TEvDone, EvDone> {};
};
16 changes: 8 additions & 8 deletions tools/actor_model/main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -21,16 +21,16 @@ int main(int argc, const char* argv[])
NActors::TActorSystem actorSystem(actorySystemSetup);
actorSystem.Start();

actorSystem.Register(CreateSelfPingActor(TDuration::Seconds(1)).Release());
Copy link
Owner

Choose a reason for hiding this comment

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

нету пингера, 4 балла


// Зарегистрируйте Write и Read акторы здесь
auto writerActorId = actorSystem.Register(CreateWriteActor().Release());
actorSystem.Register(CreateReadActor(writerActorId).Release());
actorSystem.Register(CreateSystemMonitorActor(TDuration::Seconds(1)).Release());

// Раскомментируйте этот код
// auto shouldContinue = GetProgramShouldContinue();
// while (shouldContinue->PollState() == TProgramShouldContinue::Continue) {
// Sleep(TDuration::MilliSeconds(200));
// }
auto shouldContinue = GetProgramShouldContinue();
while (shouldContinue->PollState() == TProgramShouldContinue::Continue) {
Sleep(TDuration::MilliSeconds(200));
}
actorSystem.Stop();
actorSystem.Cleanup();
// return shouldContinue->GetReturnCode();
return shouldContinue->GetReturnCode();
}