Skip to content
Merged
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
73 changes: 59 additions & 14 deletions cmd/notes/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,46 +5,91 @@ import (
"log"
"time"

"github.com/rd2w/go-notes/internal/logger"
"github.com/rd2w/go-notes/internal/model"
"github.com/rd2w/go-notes/internal/repository"
"github.com/rd2w/go-notes/internal/service"
)

// Константы приложения
const (
LoggerInterval = 200 * time.Millisecond
DataGenInterval = 500 * time.Millisecond
AppRunDuration = 6 * time.Second
GracefulShutdownDelay = 100 * time.Millisecond

EntityChanBuffer = 10

TimeFormat = "2006-01-02 15:04:05"
)

// Строковые константы
const (
AppStartMsg = "Запуск приложения с горутинами и каналами..."
DataGenStartMsg = "Запуск генерации тестовых данных..."
AppShutdownMsg = "Приложение \"Заметки\" успешно завершило выполнение программы!"
ResultsHeader = "\n=== РЕЗУЛЬТАТЫ ===\n"
NoteCountMsg = "Всего заметок создано: %d\n"
NoteDoesNotExistMsg = "Ошибка: заметка не существует"
NoteHeaderMsg = "Заметка %d:\n"
NoteIDMsg = " ID: %s\n"
NoteTitleMsg = " Заголовок: %s\n"
NoteContentMsg = " Содержимое: %s\n"
NoteCreatedAtMsg = " Создана: %s\n"
NoteUpdatedAtMsg = " Обновлена: %s\n"
)

func main() {
log.Println(AppStartMsg)
// Создаем канал для завершения
done := make(chan struct{})

// Инициализируем компоненты
repo := repository.NewRepository()
svc := service.NewService(repo)
svc := service.NewService(repo, done, DataGenInterval)
newLogger := logger.NewLogger(repo, done, LoggerInterval)

// Запускаем горутины
go newLogger.Start() // Логгер мониторит изменения
svc.Start() // Сервис запускает генерацию и сохранение данных

// Ждем некоторое время для демонстрации работы
time.Sleep(AppRunDuration)

// Сигнал завершения всем горутинам
close(done)

log.Println("Запуск генерации тестовых данных...")
svc.StartDataGeneration(1 * time.Second)
// Даем время на корректное завершение
time.Sleep(GracefulShutdownDelay)

fmt.Printf("\n=== РЕЗУЛЬТАТЫ ===\n")
fmt.Printf("Всего заметок создано: %d\n", repo.GetNotesCount())
fmt.Print(ResultsHeader)
fmt.Printf(NoteCountMsg, repo.GetNotesCount())

notes := repo.GetAllNotes()
for i, note := range notes {
displayNoteInfo(i, note)
}

log.Println("Приложение \"Заметки\" успешно завершило выполнение программы!")
log.Println(AppShutdownMsg)
}

// displayNoteInfo отображает информацию о заметке в форматированном виде
func displayNoteInfo(count int, note *model.Note) {
if note == nil {
fmt.Println("Ошибка: заметка не существует")
fmt.Println(NoteDoesNotExistMsg)
return
}

fmt.Printf("\nЗаметка %d:\n", count+1)
fmt.Printf(" ID: %s\n", note.GetID())
fmt.Printf(" Заголовок: %s\n", note.GetTitle())
fmt.Printf(" Содержимое: %s\n", note.GetContent())
fmt.Printf(" Создана: %s\n", formatTime(note.GetCreatedAt()))
fmt.Printf(" Обновлена: %s\n", formatTime(note.GetUpdatedAt()))
fmt.Printf(NoteHeaderMsg, count+1)
fmt.Printf(NoteIDMsg, note.GetID())
fmt.Printf(NoteTitleMsg, note.GetTitle())
fmt.Printf(NoteContentMsg, note.GetContent())
fmt.Printf(NoteCreatedAtMsg, formatTime(note.GetCreatedAt()))
fmt.Printf(NoteUpdatedAtMsg, formatTime(note.GetUpdatedAt()))
fmt.Println()
}

// formatTime форматирует время в едином стиле
func formatTime(t time.Time) string {
return t.Format("2006-01-02 15:04:05")
return t.Format(TimeFormat)
}
8 changes: 8 additions & 0 deletions go.mod
Original file line number Diff line number Diff line change
@@ -1,3 +1,11 @@
module github.com/rd2w/go-notes

go 1.25.3

require github.com/stretchr/testify v1.11.1

require (
github.com/davecgh/go-spew v1.1.1 // indirect
github.com/pmezard/go-difflib v1.0.0 // indirect
gopkg.in/yaml.v3 v3.0.1 // indirect
)
10 changes: 10 additions & 0 deletions go.sum
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
github.com/stretchr/testify v1.11.1 h1:7s2iGBzp5EwR7/aIZr8ao5+dra3wiQyKjjFuvgVKu7U=
github.com/stretchr/testify v1.11.1/go.mod h1:wZwfW3scLgRK+23gO65QZefKpKQRnfz6sD981Nm4B6U=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
58 changes: 58 additions & 0 deletions internal/logger/logger.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
package logger

import (
"log"
"time"

"github.com/rd2w/go-notes/internal/repository"
)

// Logger отвечает за логирование изменений в данных
type Logger struct {
repo *repository.Repository
done <-chan struct{}
interval time.Duration
}

// NewLogger создает новый экземпляр логгера
func NewLogger(repo *repository.Repository, done <-chan struct{}, interval time.Duration) *Logger {
return &Logger{
repo: repo,
done: done,
interval: interval,
}
}

// Start запускает процесс логирования изменений
func (l *Logger) Start() {
go func() {
lastNoteCount := 0
ticker := time.NewTicker(l.interval)
defer ticker.Stop()

for {
select {
case <-ticker.C:
currentNoteCount := l.repo.GetNotesCount()

if currentNoteCount > lastNoteCount {
// Получаем только новые заметки, добавленные после последней проверки
newNotes := l.repo.GetNewNotes(lastNoteCount)
log.Printf("Логгер: обнаружено %d новых заметок", len(newNotes))

for _, note := range newNotes {
log.Printf("Логгер: НОВАЯ ЗАМЕТКА - ID: %s, Заголовок: %s, Создана: %s",
note.GetID(),
note.GetTitle(),
note.GetCreatedAt().Format("15:04:05"))
}

lastNoteCount = currentNoteCount
}
case <-l.done:
log.Println("Логгер: завершение работы")
return
}
}
}()
}
Loading