Documentation
¶
Index ¶
- Constants
- Variables
- func ParseEventSummary(data []byte, v SummaryVisitor) error
- type BaselineStatus
- type BaselineValue
- type BrowserName
- type BrowserStatus
- type BrowserValue
- type Change
- type DeliveryMetadata
- type DispatchEventMetadata
- type DocLink
- type Docs
- type EmailDeliveryJob
- type EmailSubscriber
- type EventSummary
- type FeatureDiffV1SummaryGenerator
- type FeatureRef
- type IncomingEmailDeliveryJob
- type JobFrequency
- type JobTrigger
- type LatestEventInfo
- type NotificationEventCreatedV1
- type NotificationEventRequest
- type PublishEventRequest
- type Reason
- type RefreshSearchCommand
- type SavedSearchState
- type SavedSearchStateUpdateRequest
- type SavedSearchStateUpdateRequestUpdateMask
- type SearchJob
- type SplitChange
- type SubscriberSet
- type SummaryCategories
- type SummaryHighlight
- type SummaryHighlightType
- type SummaryVisitor
Constants ¶
const ( // VersionEventSummaryV1 defines the schema version for v1 of the EventSummary. VersionEventSummaryV1 = "v1" // MaxHighlights caps the number of detailed items stored in Spanner (The full highlights are stored in GCS). // Spanner's 10MB limit can easily accommodate this. // Calculation details: // A typical highlight contains: // - Feature info (ID, Name): ~50-80 bytes // - 2 DocLinks (URL, Title, Slug): ~250 bytes // - Changes metadata: ~50 bytes // - JSON structure overhead: ~50 bytes // Total ≈ 450-500 bytes. // 10,000 highlights * 500 bytes = 5MB, which is 50% of the 10MB column limit. MaxHighlights = 10000 )
const ( ReasonQueryChanged = "QUERY_CHANGED" ReasonDataUpdated = "DATA_UPDATED" )
Variables ¶
var ( ErrUnknownSummaryVersion = errors.New("unknown summary version") ErrFailedToSerializeSummary = errors.New("failed to serialize summary") ErrLatestEventNotFound = errors.New("latest event not found") )
var ( // ErrUnrecoverableSystemFailureEmailSending indicates that there's a system failure that should not be retried. // Examples: System auth issue. ErrUnrecoverableSystemFailureEmailSending = errors.New("unrecoverable user failure trying to send email") // ErrUnrecoverableUserFailureEmailSending indicates that there's a user failure that should not be retried. // Examples: Bad email address. ErrUnrecoverableUserFailureEmailSending = errors.New("unrecoverable user failure trying to send email") )
Functions ¶
func ParseEventSummary ¶
func ParseEventSummary(data []byte, v SummaryVisitor) error
ParseEventSummary handles the version detection and dispatching logic. Consumers (like the Delivery Worker) should use this instead of raw json.Unmarshal.
Types ¶
type BaselineStatus ¶
type BaselineStatus string
const ( BaselineStatusLimited BaselineStatus = "limited" BaselineStatusNewly BaselineStatus = "newly" BaselineStatusWidely BaselineStatus = "widely" BaselineStatusUnknown BaselineStatus = "unknown" )
type BaselineValue ¶
type BaselineValue struct {
Status BaselineStatus `json:"status"`
LowDate *time.Time `json:"low_date,omitempty"`
HighDate *time.Time `json:"high_date,omitempty"`
}
type BrowserName ¶
type BrowserName string
const ( BrowserChrome BrowserName = "chrome" BrowserChromeAndroid BrowserName = "chrome_android" BrowserEdge BrowserName = "edge" BrowserFirefox BrowserName = "firefox" BrowserFirefoxAndroid BrowserName = "firefox_android" BrowserSafari BrowserName = "safari" BrowserSafariIos BrowserName = "safari_ios" )
type BrowserStatus ¶
type BrowserStatus string
const ( BrowserStatusAvailable BrowserStatus = "available" BrowserStatusUnknown BrowserStatus = "" )
type BrowserValue ¶
type BrowserValue struct {
Status BrowserStatus `json:"status"`
Version *string `json:"version,omitempty"`
Date *time.Time `json:"date,omitempty"`
}
type Change ¶
type Change[T any] struct { From T `json:"from"` To T `json:"to"` }
Change represents a value transition from Old to New.
type DeliveryMetadata ¶
type DeliveryMetadata struct {
EventID string
SearchID string
Query string
Frequency JobFrequency
GeneratedAt time.Time
}
DeliveryMetadata contains the necessary context from the original event required for rendering notifications (e.g. generating links), decoupled from the upstream event format.
type DispatchEventMetadata ¶
type EmailDeliveryJob ¶
type EmailDeliveryJob struct {
SubscriptionID string
RecipientEmail string
ChannelID string
Triggers []JobTrigger
// SummaryRaw is the opaque JSON payload describing the event.
SummaryRaw []byte
// Metadata contains context for links and tracking.
Metadata DeliveryMetadata
}
EmailDeliveryJob represents a task to send an email.
type EmailSubscriber ¶
type EmailSubscriber struct {
SubscriptionID string
UserID string
Triggers []JobTrigger
EmailAddress string
ChannelID string
}
EmailSubscriber represents a subscriber using an Email channel.
type EventSummary ¶
type EventSummary struct {
SchemaVersion string `json:"schemaVersion"`
Text string `json:"text"`
Categories SummaryCategories `json:"categories,omitzero"`
Truncated bool `json:"truncated"`
Highlights []SummaryHighlight `json:"highlights"`
}
EventSummary matches the JSON structure stored in the database 'Summary' column.
type FeatureDiffV1SummaryGenerator ¶
type FeatureDiffV1SummaryGenerator struct{}
func (FeatureDiffV1SummaryGenerator) GenerateJSONSummary ¶
func (g FeatureDiffV1SummaryGenerator) GenerateJSONSummary( d v1.FeatureDiff) ([]byte, error)
GenerateJSONEventSummaryFromFeatureDiffV1 generates and serializes.
type FeatureRef ¶
type IncomingEmailDeliveryJob ¶
type IncomingEmailDeliveryJob struct {
EmailDeliveryJob
// The ID from the queued event for this specific email job.
// This will be generated by the queuing service.
// This is different from the EventID in the Metadata which is for the original event that triggered
// the event producer in the very beginning.
EmailEventID string
}
type JobFrequency ¶
type JobFrequency string
JobFrequency defines how often a saved search should be checked.
const ( FrequencyUnknown JobFrequency = "UNKNOWN" FrequencyImmediate JobFrequency = "IMMEDIATE" FrequencyWeekly JobFrequency = "WEEKLY" FrequencyMonthly JobFrequency = "MONTHLY" )
type JobTrigger ¶
type JobTrigger string
const ( FeaturePromotedToNewly JobTrigger = "FEATURE_PROMOTED_TO_NEWLY" FeaturePromotedToWidely JobTrigger = "FEATURE_PROMOTED_TO_WIDELY" FeatureRegressedToLimited JobTrigger = "FEATURE_REGRESSED_TO_LIMITED" BrowserImplementationAnyComplete JobTrigger = "BROWSER_IMPLEMENTATION_ANY_COMPLETE" )
type LatestEventInfo ¶
type NotificationEventCreatedV1 ¶
type NotificationEventCreatedV1 struct {
ID string `json:"id"`
}
NotificationEventCreatedV1 lets consumers know that a particular notification has been created.
func (NotificationEventCreatedV1) APIVersion ¶
func (e NotificationEventCreatedV1) APIVersion() string
func (NotificationEventCreatedV1) Kind ¶
func (e NotificationEventCreatedV1) Kind() string
type NotificationEventRequest ¶
type NotificationEventRequest struct {
EventID string
SearchID string
SnapshotType string
Reasons []string
DiffBlobPath string
Summary EventSummary
NewStatePath string
WorkerID string
}
NotificationEventRequest encapsulates the data needed to insert a row into the Events table.
type PublishEventRequest ¶
type RefreshSearchCommand ¶
type RefreshSearchCommand struct {
SearchID string
Query string
Frequency JobFrequency
Timestamp time.Time
}
type SavedSearchState ¶
type SavedSearchState struct {
StateBlobPath *string
}
type SavedSearchStateUpdateRequest ¶
type SavedSearchStateUpdateRequest struct {
StateBlobPath *string
UpdateMask []SavedSearchStateUpdateRequestUpdateMask
}
type SavedSearchStateUpdateRequestUpdateMask ¶
type SavedSearchStateUpdateRequestUpdateMask string
const (
SavedSearchStateUpdateRequestStateBlobPath SavedSearchStateUpdateRequestUpdateMask = "state_blob_path"
)
type SplitChange ¶
type SplitChange struct {
From FeatureRef `json:"from"`
To []FeatureRef `json:"to"`
}
type SubscriberSet ¶
type SubscriberSet struct {
Emails []EmailSubscriber
}
SubscriberSet groups subscribers by channel type to avoid runtime type assertions.
type SummaryCategories ¶
type SummaryCategories struct {
QueryChanged int `json:"query_changed,omitzero"`
Added int `json:"added,omitzero"`
Removed int `json:"removed,omitzero"`
Deleted int `json:"deleted,omitzero"`
Moved int `json:"moved,omitzero"`
Split int `json:"split,omitzero"`
Updated int `json:"updated,omitzero"`
UpdatedImpl int `json:"updated_impl,omitzero"`
UpdatedRename int `json:"updated_rename,omitzero"`
UpdatedBaseline int `json:"updated_baseline,omitzero"`
}
SummaryCategories defines the specific counts for different change types.
type SummaryHighlight ¶
type SummaryHighlight struct {
Type SummaryHighlightType `json:"type"`
FeatureID string `json:"feature_id"`
FeatureName string `json:"feature_name"`
Docs *Docs `json:"docs,omitempty"`
// Strongly typed change fields to support i18n and avoid interface{}
NameChange *Change[string] `json:"name_change,omitempty"`
BaselineChange *Change[BaselineValue] `json:"baseline_change,omitempty"`
BrowserChanges map[BrowserName]*Change[BrowserValue] `json:"browser_changes,omitempty"`
Moved *Change[FeatureRef] `json:"moved,omitempty"`
Split *SplitChange `json:"split,omitempty"`
}
func (SummaryHighlight) MatchesTrigger ¶
func (h SummaryHighlight) MatchesTrigger(t JobTrigger) bool
type SummaryHighlightType ¶
type SummaryHighlightType string
const ( SummaryHighlightTypeAdded SummaryHighlightType = "Added" SummaryHighlightTypeRemoved SummaryHighlightType = "Removed" SummaryHighlightTypeChanged SummaryHighlightType = "Changed" SummaryHighlightTypeMoved SummaryHighlightType = "Moved" SummaryHighlightTypeSplit SummaryHighlightType = "Split" SummaryHighlightTypeDeleted SummaryHighlightType = "Deleted" )
type SummaryVisitor ¶
type SummaryVisitor interface {
VisitV1(s EventSummary) error
}
SummaryVisitor defines the contract for consuming immutable Event Summaries. Unlike state blobs which are migrated to the latest schema, summaries are historical records that should be rendered as-is. The Visitor pattern forces consumers to explicitly handle each schema version (e.g. V1, V2) independently.
Directories
¶
| Path | Synopsis |
|---|---|
|
Named comparables instead of comparable to not conflict with the standard library's "comparable" interface
|
Named comparables instead of comparable to not conflict with the standard library's "comparable" interface |