Documentation
¶
Index ¶
- type CampaignStats
- type ConfigSummary
- type EmailStatus
- type LogEntry
- type Monitor
- type NoOpMonitor
- func (n *NoOpMonitor) AddLogEntry(level, message, email string)
- func (n *NoOpMonitor) AddSMTPResponse(code string)
- func (n *NoOpMonitor) InitializeCampaign(jobID string, config ConfigSummary, totalRecipients int)
- func (n *NoOpMonitor) InitializePending(emails []string)
- func (n *NoOpMonitor) UpdateRecipientStatus(email string, status EmailStatus, duration time.Duration, errorMsg string)
- type RecipientStatus
- type SSEClient
- type Server
- func (s *Server) AddLogEntry(level, message, email string)
- func (s *Server) AddSMTPResponse(code string)
- func (s *Server) GetRecipients() []RecipientStatus
- func (s *Server) GetStats() CampaignStats
- func (s *Server) InitializeCampaign(jobID string, config ConfigSummary, totalRecipients int)
- func (s *Server) InitializePending(emails []string)
- func (s *Server) Start() error
- func (s *Server) Stop() error
- func (s *Server) UpdateRecipientStatus(email string, status EmailStatus, duration time.Duration, errorMsg string)
Constants ¶
This section is empty.
Variables ¶
This section is empty.
Functions ¶
This section is empty.
Types ¶
type CampaignStats ¶
type CampaignStats struct {
JobID string `json:"job_id"`
StartTime time.Time `json:"start_time"`
TotalRecipients int `json:"total_recipients"`
PendingCount int `json:"pending_count"`
SendingCount int `json:"sending_count"`
SentCount int `json:"sent_count"`
FailedCount int `json:"failed_count"`
RetryCount int `json:"retry_count"`
EmailsPerSecond float64 `json:"emails_per_second"`
EstimatedTimeLeft string `json:"estimated_time_left"`
AvgDurationMs float64 `json:"avg_duration_ms"`
Recipients map[string]*RecipientStatus `json:"recipients"`
DomainBreakdown map[string]int `json:"domain_breakdown"`
SMTPResponseCodes map[string]int `json:"smtp_response_codes"`
ConfigSummary ConfigSummary `json:"config_summary"`
LogEntries []LogEntry `json:"log_entries"`
}
CampaignStats represents real-time campaign statistics
type ConfigSummary ¶
type ConfigSummary struct {
CSVFile string `json:"csv_file"`
SheetURL string `json:"sheet_url"`
TemplateFile string `json:"template_file"`
ConcurrentWorkers int `json:"concurrent_workers"`
BatchSize int `json:"batch_size"`
RetryLimit int `json:"retry_limit"`
FilterExpression string `json:"filter_expression"`
}
ConfigSummary holds campaign configuration details
type EmailStatus ¶
type EmailStatus string
EmailStatus represents the status of an individual email
const ( StatusPending EmailStatus = "pending" StatusSending EmailStatus = "sending" StatusSent EmailStatus = "sent" StatusFailed EmailStatus = "failed" StatusRetry EmailStatus = "retry" )
type LogEntry ¶
type LogEntry struct {
Timestamp time.Time `json:"timestamp"`
Level string `json:"level"`
Message string `json:"message"`
Email string `json:"email,omitempty"`
}
LogEntry represents a monitoring log entry
type Monitor ¶
type Monitor interface {
// InitializeCampaign sets up campaign tracking
InitializeCampaign(jobID string, config ConfigSummary, totalRecipients int)
// InitializePending registers a batch of recipients in the Pending state
// under a single lock acquisition. Use this in place of N sequential
// UpdateRecipientStatus calls when seeding the dashboard at dispatch start.
InitializePending(emails []string)
// UpdateRecipientStatus updates the status of a specific recipient
UpdateRecipientStatus(email string, status EmailStatus, duration time.Duration, errorMsg string)
// AddSMTPResponse records an SMTP response code
AddSMTPResponse(code string)
// AddLogEntry adds a log entry to the monitoring dashboard
AddLogEntry(level, message, email string)
}
Monitor interface for reporting email sending progress
type NoOpMonitor ¶
type NoOpMonitor struct{}
NoOpMonitor is a monitor that does nothing (null object pattern)
func (*NoOpMonitor) AddLogEntry ¶
func (n *NoOpMonitor) AddLogEntry(level, message, email string)
func (*NoOpMonitor) AddSMTPResponse ¶
func (n *NoOpMonitor) AddSMTPResponse(code string)
func (*NoOpMonitor) InitializeCampaign ¶
func (n *NoOpMonitor) InitializeCampaign(jobID string, config ConfigSummary, totalRecipients int)
func (*NoOpMonitor) InitializePending ¶
func (n *NoOpMonitor) InitializePending(emails []string)
func (*NoOpMonitor) UpdateRecipientStatus ¶
func (n *NoOpMonitor) UpdateRecipientStatus(email string, status EmailStatus, duration time.Duration, errorMsg string)
type RecipientStatus ¶
type RecipientStatus struct {
Email string `json:"email"`
Status EmailStatus `json:"status"`
Attempts int `json:"attempts"`
LastAttempt time.Time `json:"last_attempt"`
Error string `json:"error,omitempty"`
Duration int64 `json:"duration_ms"` // Duration in milliseconds
// contains filtered or unexported fields
}
RecipientStatus tracks the status of a single recipient
type SSEClient ¶
type SSEClient struct {
Chan chan CampaignStats
RemoteAddr string
// contains filtered or unexported fields
}
SSEClient represents a connected SSE client with atomic last-active tracking.
type Server ¶
type Server struct {
// contains filtered or unexported fields
}
Server provides real-time monitoring dashboard
func NewServer ¶
NewServer creates a new monitoring server. clientTimeout controls how long an idle SSE connection is kept alive; pass 0 to use the 5-minute default.
func (*Server) AddLogEntry ¶
AddLogEntry adds a log entry to the monitoring dashboard
func (*Server) AddSMTPResponse ¶
AddSMTPResponse records an SMTP response code
func (*Server) GetRecipients ¶
func (s *Server) GetRecipients() []RecipientStatus
GetRecipients returns a slice of recipient statuses for the dashboard table.
func (*Server) GetStats ¶
func (s *Server) GetStats() CampaignStats
GetStats returns a shallow copy of the current campaign stats.
func (*Server) InitializeCampaign ¶
func (s *Server) InitializeCampaign(jobID string, config ConfigSummary, totalRecipients int)
InitializeCampaign initializes campaign tracking
func (*Server) InitializePending ¶
InitializePending registers a batch of recipients in the Pending state under a single lock acquisition, skipping the per-recipient broadcast/metrics work that UpdateRecipientStatus performs. Use at dispatch start to seed the dashboard with O(N) recipients without N broadcaster wake-ups.
func (*Server) UpdateRecipientStatus ¶
func (s *Server) UpdateRecipientStatus(email string, status EmailStatus, duration time.Duration, errorMsg string)
UpdateRecipientStatus updates the status of a specific recipient. The actual SSE broadcast is debounced via the broadcaster goroutine.