world

package
v0.0.0-...-53f8b62 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Dec 13, 2024 License: MIT Imports: 21 Imported by: 0

Documentation

Index

Constants

View Source
const (
	// InitialFare 初乗り運賃
	InitialFare = 500
	// FarePerDistance 1距離あたりの運賃
	FarePerDistance = 100
)
View Source
const (
	// LengthOfMinute 仮想世界の1分の長さ
	LengthOfMinute = 1 // 1Tickが1分
	// LengthOfHour 仮想世界の1時間の長さ
	LengthOfHour = LengthOfMinute * 60
	// LengthOfDay 仮想世界の1日の長さ
	LengthOfDay = LengthOfHour * 24
)
View Source
const (
	ErrorLimit = 200
)
View Source
const ForwardingScoreDenominator = 10

Variables

View Source
var ErrorTexts = map[ErrorCode]string{
	ErrorCodeFailedToSendChairCoordinate:                    "椅子の座標送信に失敗しました",
	ErrorCodeFailedToDepart:                                 "椅子が出発できませんでした",
	ErrorCodeFailedToAcceptRequest:                          "椅子がライドを受理できませんでした",
	ErrorCodeFailedToEvaluate:                               "ユーザーのライド評価に失敗しました",
	ErrorCodeEvaluateTimeout:                                "ユーザーのライド評価がタイムアウトしました",
	ErrorCodeFailedToCheckRequestHistory:                    "ユーザーがライド履歴の取得に失敗しました",
	ErrorCodeFailedToCreateRequest:                          "ユーザーが新しくライドを作成できませんでした",
	ErrorCodeUserNotRequestingButStatusChanged:              "ユーザーが想定していない通知を受け取りました",
	ErrorCodeChairNotAssignedButStatusChanged:               "椅子が想定していない通知を受け取りました",
	ErrorCodeUnexpectedUserRequestStatusTransitionOccurred:  "ユーザーに想定していないライドの状態遷移の通知がありました",
	ErrorCodeUnexpectedChairRequestStatusTransitionOccurred: "椅子に想定していないライドの状態遷移の通知がありました",
	ErrorCodeFailedToActivate:                               "椅子がアクティベートに失敗しました",
	ErrorCodeChairAlreadyHasRequest:                         "椅子がライドの完了通知を受け取る前に、別の新しいライドの通知を受け取りました",
	ErrorCodeFailedToRegisterUser:                           "ユーザー登録に失敗しました",
	ErrorCodeFailedToRegisterOwner:                          "オーナー登録に失敗しました",
	ErrorCodeFailedToRegisterChair:                          "椅子登録に失敗しました",
	ErrorCodeFailedToConnectNotificationStream:              "通知APIの接続に失敗しました",
	ErrorCodeFailedToRegisterPaymentMethods:                 "ユーザーの支払い情報の登録に失敗しました",
	ErrorCodeFailedToGetOwnerSales:                          "オーナーの売り上げ情報の取得に失敗しました",
	ErrorCodeSalesMismatched:                                "取得したオーナーの売り上げ情報が想定しているものと異なります",
	ErrorCodeFailedToGetOwnerChairs:                         "オーナーの椅子一覧の取得に失敗しました",
	ErrorCodeIncorrectOwnerChairsData:                       "取得したオーナーの椅子一覧の情報が想定しているものと異なります",
	ErrorCodeTooOldNearbyChairsResponse:                     "取得した付近の椅子情報が古すぎます",
	ErrorCodeChairReceivedDataIsWrong:                       "椅子が受け取った通知の内容が想定と異なります",
	ErrorCodeWrongNearbyChairs:                              "取得した付近の椅子情報に不備があります",
	ErrorCodeLackOfNearbyChairs:                             "付近の椅子情報が想定よりも足りていません",
	ErrorCodeMatchingTimeout:                                "ライドが長時間マッチングされませんでした",
	ErrorCodeUserReceivedDataIsWrong:                        "ユーザーが受け取った通知の内容が想定と異なります",
	ErrorCodeSkippedPaymentButEvaluated:                     "評価は完了しているが、支払いが行われていないライドが存在します",
	ErrorCodeWrongPaymentRequest:                            "決済サーバーに誤った支払いがリクエストされました",
}

Functions

func CodeError

func CodeError(code ErrorCode) error

func ConvertHour

func ConvertHour[T constraints.Integer](h T) T

ConvertHour h時間を仮想世界時間に変換する

func IsCriticalError

func IsCriticalError(err error) bool

func PickModels

func PickModels() map[int]ChairModels

func RandomTwoCoordinateWithRand

func RandomTwoCoordinateWithRand(region *Region, distance int, rand *rand.Rand) (Coordinate, Coordinate)

func UnwrapMultiError

func UnwrapMultiError(err error) ([]error, bool)

func WrapCodeError

func WrapCodeError(code ErrorCode, err error) error

Types

type AppChair

type AppChair struct {
	ID         string
	Name       string
	Model      string
	Coordinate Coordinate
}

type Chair

type Chair struct {
	// ID ベンチマーカー内部椅子ID
	ID ChairID
	// ServerID サーバー上での椅子ID
	ServerID string
	// World Worldへの逆参照
	World *World
	// Region 椅子がいる地域
	Region *Region
	// Owner 椅子を所有しているオーナー
	Owner *Owner
	// Model 椅子のモデル
	Model *ChairModel
	// State 椅子の状態
	State ChairState
	// Location 椅子の位置情報
	Location ChairLocation
	// RegisteredData サーバーに登録されている椅子情報
	RegisteredData RegisteredChairData

	// Request 進行中のリクエスト
	Request *Request
	// RequestHistory 引き受けたリクエストの履歴
	RequestHistory *concurrent.SimpleSlice[*Request]
	// Client webappへのクライアント
	Client ChairClient
	// Rand 専用の乱数
	Rand *rand.Rand
	// ActivatedAt Active化レスポンスが返ってきた日時
	ActivatedAt time.Time
	// contains filtered or unexported fields
}

func (*Chair) GetServerID

func (c *Chair) GetServerID() string

func (*Chair) HandleNotification

func (c *Chair) HandleNotification(event NotificationEvent) error

func (*Chair) SetID

func (c *Chair) SetID(id ChairID)

func (*Chair) String

func (c *Chair) String() string

func (*Chair) Tick

func (c *Chair) Tick(ctx *Context) error

func (*Chair) ValidateChairNotificationEvent

func (c *Chair) ValidateChairNotificationEvent(rideID string, event ChairNotificationEvent) error

type ChairClient

type ChairClient interface {
	// SendChairCoordinate サーバーに椅子の座標を送信する
	SendChairCoordinate(ctx *Context, chair *Chair) (*SendChairCoordinateResponse, error)
	// SendAcceptRequest サーバーに配椅子要求を受理することを報告する
	SendAcceptRequest(ctx *Context, chair *Chair, req *Request) error
	// SendDepart サーバーに客が搭乗完了して出発することを報告する
	SendDepart(ctx *Context, req *Request) error
	// SendActivate サーバーにリクエストの受付開始を通知する
	SendActivate(ctx *Context, chair *Chair) error
	// ConnectChairNotificationStream 椅子用の通知ストリームに接続する
	ConnectChairNotificationStream(ctx *Context, chair *Chair, receiver NotificationReceiverFunc) (NotificationStream, error)
}

type ChairID

type ChairID int

type ChairLocation

type ChairLocation struct {
	// Initial 初期位置
	Initial Coordinate
	// contains filtered or unexported fields
}

func (*ChairLocation) Current

func (r *ChairLocation) Current() Coordinate

func (*ChairLocation) Dirty

func (r *ChairLocation) Dirty() bool

func (*ChairLocation) GetCoordByTime

func (r *ChairLocation) GetCoordByTime(t time.Time) Coordinate

func (*ChairLocation) GetLocationEntryByTime

func (r *ChairLocation) GetLocationEntryByTime(t time.Time) *LocationEntry

func (*ChairLocation) GetPeriodsByCoord

func (r *ChairLocation) GetPeriodsByCoord(c Coordinate) []GetPeriodsByCoordResultEntry

func (*ChairLocation) LastMovedAt

func (r *ChairLocation) LastMovedAt() (time.Time, bool)

func (*ChairLocation) MoveTo

func (r *ChairLocation) MoveTo(location *LocationEntry)

MoveTo 椅子をlocationに移動させ、総移動距離を加算する

func (*ChairLocation) PlaceTo

func (r *ChairLocation) PlaceTo(location *LocationEntry)

PlaceTo 椅子をlocationに配置する。前回の位置との距離差を総移動距離には加算しない

func (*ChairLocation) ResetDirtyFlag

func (r *ChairLocation) ResetDirtyFlag()

func (*ChairLocation) SetServerTime

func (r *ChairLocation) SetServerTime(serverTime time.Time)

func (*ChairLocation) TotalTravelDistance

func (r *ChairLocation) TotalTravelDistance() int

func (*ChairLocation) TotalTravelDistanceUntil

func (r *ChairLocation) TotalTravelDistanceUntil(until time.Time) int

type ChairModel

type ChairModel struct {
	Name  string
	Speed int
}

func PickRandomModel

func PickRandomModel() *ChairModel

func (*ChairModel) GenerateName

func (m *ChairModel) GenerateName() string

type ChairModels

type ChairModels []*ChairModel

func (ChairModels) Random

func (arr ChairModels) Random() *ChairModel

type ChairNotificationEvent

type ChairNotificationEvent struct {
	User        ChairNotificationEventUserPayload
	Pickup      Coordinate
	Destination Coordinate
}

type ChairNotificationEventArrived

type ChairNotificationEventArrived struct {
	ServerRequestID string
	ChairNotificationEvent
	// contains filtered or unexported fields
}

type ChairNotificationEventCarrying

type ChairNotificationEventCarrying struct {
	ServerRequestID string
	ChairNotificationEvent
	// contains filtered or unexported fields
}

type ChairNotificationEventCompleted

type ChairNotificationEventCompleted struct {
	ServerRequestID string
	ChairNotificationEvent
	// contains filtered or unexported fields
}

type ChairNotificationEventDispatched

type ChairNotificationEventDispatched struct {
	ServerRequestID string
	ChairNotificationEvent
	// contains filtered or unexported fields
}

type ChairNotificationEventDispatching

type ChairNotificationEventDispatching struct {
	ServerRequestID string
	ChairNotificationEvent
	// contains filtered or unexported fields
}

type ChairNotificationEventMatched

type ChairNotificationEventMatched struct {
	ServerRequestID string
	ChairNotificationEvent
	// contains filtered or unexported fields
}

type ChairNotificationEventUserPayload

type ChairNotificationEventUserPayload struct {
	ID   string
	Name string
}

type ChairSales

type ChairSales struct {
	ID    string
	Name  string
	Sales int
}

type ChairSalesPerModel

type ChairSalesPerModel struct {
	Model string
	Sales int
}

type ChairState

type ChairState int
const (
	ChairStateInactive ChairState = iota
	ChairStateActive
)

type Context

type Context struct {
	// contains filtered or unexported fields
}

func NewContext

func NewContext(world *World) *Context

func (*Context) ContestantLogger

func (c *Context) ContestantLogger() *slog.Logger

func (*Context) CurrentTime

func (c *Context) CurrentTime() int64

type Coordinate

type Coordinate struct {
	X int
	Y int
}

Coordinate 座標

func C

func C(x, y int) Coordinate

func CalculateRandomDetourPoint

func CalculateRandomDetourPoint(start, dest Coordinate, speed int, rand *rand.Rand) Coordinate

func RandomCoordinate

func RandomCoordinate(worldX, worldY int) Coordinate

func RandomCoordinateAwayFromHereWithRand

func RandomCoordinateAwayFromHereWithRand(here Coordinate, distance int, rand *rand.Rand) Coordinate

func RandomCoordinateOnRegion

func RandomCoordinateOnRegion(region *Region) Coordinate

func RandomCoordinateOnRegionWithRand

func RandomCoordinateOnRegionWithRand(region *Region, rand *rand.Rand) Coordinate

func RandomCoordinateWithRand

func RandomCoordinateWithRand(worldX, worldY int, rand *rand.Rand) Coordinate

func (Coordinate) DistanceTo

func (c Coordinate) DistanceTo(c2 Coordinate) int

DistanceTo c2までのマンハッタン距離

func (Coordinate) Equals

func (c Coordinate) Equals(c2 Coordinate) bool

func (Coordinate) MoveToward

func (c Coordinate) MoveToward(target Coordinate, step int, rand *rand.Rand) Coordinate

func (Coordinate) String

func (c Coordinate) String() string

func (Coordinate) Within

func (c Coordinate) Within(region *Region) bool

Within 座標がregion内にあるかどうか

type CreateChairArgs

type CreateChairArgs struct {
	// Owner 椅子のオーナー
	Owner *Owner
	// InitialCoordinate 椅子の初期位置
	InitialCoordinate Coordinate
	// Model 椅子モデル
	Model *ChairModel
}

type CreateOwnerArgs

type CreateOwnerArgs struct {
	// Region 椅子を配置する地域
	Region *Region
}

type CreateUserArgs

type CreateUserArgs struct {
	// Region ユーザーを配置する地域
	Region *Region
	// Inviter 招待したユーザー
	Inviter *User
}

type DBEntry

type DBEntry[K ~int] interface {
	SetID(id K)
	GetServerID() string
}

type ErrorCode

type ErrorCode int
const (
	// ErrorCodeUnknown 不明なエラー
	ErrorCodeUnknown ErrorCode = iota
	// ErrorCodeFailedToSendChairCoordinate 椅子の座標送信リクエストが失敗した
	ErrorCodeFailedToSendChairCoordinate
	// ErrorCodeFailedToDepart 椅子が出発しようとしたが、departリクエストが失敗した
	ErrorCodeFailedToDepart
	// ErrorCodeFailedToAcceptRequest 椅子がリクエストを受理しようとしたが失敗した
	ErrorCodeFailedToAcceptRequest

	// ErrorCodeFailedToEvaluate ユーザーが送迎の評価をしようとしたが失敗した
	ErrorCodeFailedToEvaluate
	// ErrorCodeEvaluateTimeout ユーザーが送迎の評価をしようとしたがタイムアウトした
	ErrorCodeEvaluateTimeout
	// ErrorCodeFailedToCheckRequestHistory ユーザーがリクエスト履歴を確認しようとしたが失敗した
	ErrorCodeFailedToCheckRequestHistory
	// ErrorCodeFailedToCreateRequest ユーザーがリクエストを作成しようとしたが失敗した
	ErrorCodeFailedToCreateRequest
	// ErrorCodeUserNotRequestingButStatusChanged リクエストしていないユーザーのリクエストステータスが更新された
	ErrorCodeUserNotRequestingButStatusChanged
	// ErrorCodeChairNotAssignedButStatusChanged 椅子にリクエストが割り当てられていないのに、椅子のステータスが更新された
	ErrorCodeChairNotAssignedButStatusChanged
	// ErrorCodeUnexpectedUserRequestStatusTransitionOccurred 想定されていないユーザーのRequestStatusの遷移が発生した
	ErrorCodeUnexpectedUserRequestStatusTransitionOccurred
	// ErrorCodeUnexpectedChairRequestStatusTransitionOccurred 想定されていない椅子のRequestStatusの遷移が発生した
	ErrorCodeUnexpectedChairRequestStatusTransitionOccurred
	// ErrorCodeFailedToActivate 椅子がリクエストの受付を開始しようとしたが失敗した
	ErrorCodeFailedToActivate

	// ErrorCodeChairAlreadyHasRequest 既にリクエストが割り当てられている椅子に、別のリクエストが割り当てられた
	ErrorCodeChairAlreadyHasRequest

	// ErrorCodeFailedToRegisterUser ユーザー登録に失敗した
	ErrorCodeFailedToRegisterUser
	// ErrorCodeFailedToRegisterOwner オーナー登録に失敗した
	ErrorCodeFailedToRegisterOwner
	// ErrorCodeFailedToRegisterChair 椅子登録に失敗した
	ErrorCodeFailedToRegisterChair
	// ErrorCodeFailedToConnectNotificationStream 通知ストリームへの接続に失敗した
	ErrorCodeFailedToConnectNotificationStream
	// ErrorCodeFailedToRegisterPaymentMethods ユーザーの支払い情報の登録に失敗した
	ErrorCodeFailedToRegisterPaymentMethods
	// ErrorCodeFailedToGetOwnerSales オーナーの売り上げ情報の取得に失敗した
	ErrorCodeFailedToGetOwnerSales

	// ErrorCodeSalesMismatched 取得したオーナーの売り上げ情報が想定しているものとズレています
	ErrorCodeSalesMismatched
	// ErrorCodeFailedToGetOwnerChairs オーナーの椅子一覧の取得に失敗した
	ErrorCodeFailedToGetOwnerChairs
	// ErrorCodeIncorrectOwnerChairsData 取得したオーナーの椅子一覧の情報が合ってない
	ErrorCodeIncorrectOwnerChairsData
	// ErrorCodeTooOldNearbyChairsResponse 取得した付近の椅子情報が古すぎます
	ErrorCodeTooOldNearbyChairsResponse

	// ErrorCodeChairReceivedDataIsWrong 椅子が通知から受け取ったデータが想定と異なります
	ErrorCodeChairReceivedDataIsWrong
	// ErrorCodeWrongNearbyChairs 取得した付近の椅子情報に不備があります
	ErrorCodeWrongNearbyChairs
	// ErrorCodeLackOfNearbyChairs 取得した付近の椅子情報が足りません
	ErrorCodeLackOfNearbyChairs
	// ErrorCodeMatchingTimeout マッチングに時間がかかりすぎです
	ErrorCodeMatchingTimeout
	// ErrorCodeUserReceivedDataIsWrong ユーザーが通知から受け取ったデータが想定と異なります
	ErrorCodeUserReceivedDataIsWrong
	// ErrorCodeSkippedPaymentButEvaluated 評価が完了しているのに、支払いが行われていないライドが存在します
	ErrorCodeSkippedPaymentButEvaluated
	// ErrorCodeWrongPaymentRequest 決済サーバーに誤った支払いがリクエストされました
	ErrorCodeWrongPaymentRequest
)

func GetErrorCode

func GetErrorCode(err error) ErrorCode

type ErrorCounter

type ErrorCounter struct {
	// contains filtered or unexported fields
}

func NewErrorCounter

func NewErrorCounter() *ErrorCounter

func (*ErrorCounter) Add

func (c *ErrorCounter) Add(err error) error

func (*ErrorCounter) Count

func (c *ErrorCounter) Count() map[ErrorCode]int

func (*ErrorCounter) Total

func (c *ErrorCounter) Total() int

type Evaluation

type Evaluation struct {
	Matching bool
	Dispatch bool
	Pickup   bool
	Drive    bool
}

func (Evaluation) Map

func (e Evaluation) Map() [4]bool

func (Evaluation) Score

func (e Evaluation) Score() int

func (Evaluation) String

func (e Evaluation) String() string

type Event

type Event interface {
	// contains filtered or unexported methods
}

type EventRequestCompleted

type EventRequestCompleted struct {
	Request *Request
	// contains filtered or unexported fields
}

type EventSoftError

type EventSoftError struct {
	Error error
	// contains filtered or unexported fields
}

type EventUserActivated

type EventUserActivated struct {
	User *User
	// contains filtered or unexported fields
}

type EventUserLeave

type EventUserLeave struct {
	User *User
	// contains filtered or unexported fields
}

type GenericDB

type GenericDB[K ~int, V DBEntry[K]] struct {
	// contains filtered or unexported fields
}

func NewGenericDB

func NewGenericDB[K ~int, V DBEntry[K]]() *GenericDB[K, V]

func (*GenericDB[K, V]) Create

func (db *GenericDB[K, V]) Create(v V) V

func (*GenericDB[K, V]) Get

func (db *GenericDB[K, V]) Get(id K) V

func (*GenericDB[K, V]) GetByServerID

func (db *GenericDB[K, V]) GetByServerID(serverID string) V

func (*GenericDB[K, V]) Iter

func (db *GenericDB[K, V]) Iter() iter.Seq2[K, V]

func (*GenericDB[K, V]) Size

func (db *GenericDB[K, V]) Size() int

func (*GenericDB[K, V]) ToSlice

func (db *GenericDB[K, V]) ToSlice() []V

func (*GenericDB[K, V]) Values

func (db *GenericDB[K, V]) Values() iter.Seq[V]

type GetEstimatedFareResponse

type GetEstimatedFareResponse struct {
	Fare     int
	Discount int
}

type GetNearbyChairsResponse

type GetNearbyChairsResponse struct {
	RetrievedAt time.Time
	Chairs      []*AppChair
}

type GetOwnerChairsRequest

type GetOwnerChairsRequest struct{}

type GetOwnerChairsResponse

type GetOwnerChairsResponse struct {
	Chairs []*OwnerChair
}

type GetOwnerSalesRequest

type GetOwnerSalesRequest struct {
	Since time.Time
	Until time.Time
}

type GetOwnerSalesResponse

type GetOwnerSalesResponse struct {
	Total  int
	Chairs []*ChairSales
	Models []*ChairSalesPerModel
}

type GetPeriodsByCoordResultEntry

type GetPeriodsByCoordResultEntry struct {
	Since time.Time
	Until null.Time
}

type GetRequestsResponse

type GetRequestsResponse struct {
	Requests []*RequestHistory
}

type Interval

type Interval[T constraints.Integer | constraints.Float] struct {
	Left  T
	Right T
}

Interval 閉区間

func NewInterval

func NewInterval[T constraints.Integer | constraints.Float](left T, right T) Interval[T]

func (*Interval[T]) Include

func (i *Interval[T]) Include(v T) bool

Include 閉区間にvが含まれるかどうか

func (*Interval[T]) String

func (i *Interval[T]) String() string

type LocationEntry

type LocationEntry struct {
	Coord      Coordinate
	Time       int64
	ServerTime null.Time
}

type NotificationEvent

type NotificationEvent interface {
	// contains filtered or unexported methods
}

type NotificationReceiverFunc

type NotificationReceiverFunc func(event NotificationEvent)

type NotificationStream

type NotificationStream interface {
	Close()
}

type Owner

type Owner struct {
	// ID ベンチマーカー内部オーナーID
	ID OwnerID
	// ServerID サーバー上でのオーナーID
	ServerID string
	// World Worldへの逆参照
	World *World
	// Region 椅子を配置する地域
	Region *Region
	// ChairDB 管理している椅子
	ChairDB *concurrent.SimpleMap[ChairID, *Chair]
	// TotalSales 管理している椅子による売上の合計
	TotalSales atomic.Int64
	// SubScore このオーナーが管理している椅子によって獲得したベンチマークスコアの合計
	SubScore atomic.Int64
	// CompletedRequest 管理している椅子が完了したリクエスト
	CompletedRequest *concurrent.SimpleSlice[*Request]
	// ChairModels このオーナーが取り扱っているモデル
	ChairModels map[int]ChairModels

	// RegisteredData サーバーに登録されているオーナー情報
	RegisteredData RegisteredOwnerData

	// Client webappへのクライアント
	Client OwnerClient
	// Rand 専用の乱数
	Rand *rand.Rand
	// contains filtered or unexported fields
}

func (*Owner) AddChair

func (p *Owner) AddChair(c *Chair)

func (*Owner) GetServerID

func (p *Owner) GetServerID() string

func (*Owner) SetID

func (p *Owner) SetID(id OwnerID)

func (*Owner) String

func (p *Owner) String() string

func (*Owner) Tick

func (p *Owner) Tick(ctx *Context) error

func (*Owner) ValidateChairs

func (p *Owner) ValidateChairs(serverSide *GetOwnerChairsResponse, baseTime time.Time) error

func (*Owner) ValidateSales

func (p *Owner) ValidateSales(until time.Time, serverSide *GetOwnerSalesResponse, snapshot []*Request) error

type OwnerChair

type OwnerChair struct {
	ID                     string
	Name                   string
	Model                  string
	Active                 bool
	RegisteredAt           time.Time
	TotalDistance          int
	TotalDistanceUpdatedAt null.Time
}

type OwnerClient

type OwnerClient interface {
	// GetOwnerSales サーバーからオーナーの売り上げ情報を取得する
	GetOwnerSales(ctx *Context, args *GetOwnerSalesRequest) (*GetOwnerSalesResponse, error)
	// GetOwnerChairs サーバーからオーナーの椅子一覧を取得する
	GetOwnerChairs(ctx *Context, args *GetOwnerChairsRequest) (*GetOwnerChairsResponse, error)
	// BrowserAccess ブラウザでアクセスしたときのリクエストを送信する
	BrowserAccess(ctx *Context, scenario benchrun.FrontendPathScenario) error
}

type OwnerID

type OwnerID int

type PaymentDB

type PaymentDB struct {
	PaymentTokens     *concurrent.SimpleMap[string, *User]
	CommittedPayments *concurrent.SimpleSlice[*payment.Payment]
}

func NewPaymentDB

func NewPaymentDB() *PaymentDB

func (*PaymentDB) TotalPayment

func (db *PaymentDB) TotalPayment() int64

func (*PaymentDB) Verify

func (db *PaymentDB) Verify(p *payment.Payment) payment.Status

type Region

type Region struct {
	Name          string
	RegionOffsetX int
	RegionOffsetY int
	RegionWidth   int
	RegionHeight  int
	// UsersDB 地域内のユーザー
	UsersDB *concurrent.SimpleMap[UserID, *User]
	// TotalEvaluation 地域内のユーザーのリクエストの平均評価の合計値
	TotalEvaluation atomic.Int32
	// contains filtered or unexported fields
}

func NewRegion

func NewRegion(name string, offsetX, offsetY, width, height int) *Region

func (*Region) ActiveUserNum

func (r *Region) ActiveUserNum() int

ActiveUserNum Regionの現在のアクティブユーザー数

func (*Region) AddUser

func (r *Region) AddUser(u *User)

AddUser Regionにユーザーを追加する

func (*Region) Contains

func (r *Region) Contains(c Coordinate) bool

Contains Regionが座標cを含んでいるかどうか

func (*Region) RangeX

func (r *Region) RangeX() (left, right int)

RangeX RegionのX座標の範囲

func (*Region) RangeY

func (r *Region) RangeY() (bottom, top int)

RangeY RegionのY座標の範囲

func (*Region) UserLeave

func (r *Region) UserLeave(u *User) bool

UserLeave Regionからユーザーが離脱可能なら離脱させる

func (*Region) UserSatisfactionScore

func (r *Region) UserSatisfactionScore() int

UserSatisfactionScore 地域内のユーザーの満足度

type RegisterChairRequest

type RegisterChairRequest struct {
	Name  string
	Model string
}

type RegisterChairResponse

type RegisterChairResponse struct {
	ServerChairID string
	ServerOwnerID string

	Client ChairClient
}

type RegisterOwnerRequest

type RegisterOwnerRequest struct {
	Name string
}

type RegisterOwnerResponse

type RegisterOwnerResponse struct {
	ServerOwnerID        string
	ChairRegisteredToken string

	Client OwnerClient
}

type RegisterUserRequest

type RegisterUserRequest struct {
	UserName       string
	FirstName      string
	LastName       string
	DateOfBirth    string
	InvitationCode string
}

type RegisterUserResponse

type RegisterUserResponse struct {
	ServerUserID   string
	InvitationCode string

	Client UserClient
}

type RegisteredChairData

type RegisteredChairData struct {
	Name string
}

type RegisteredOwnerData

type RegisteredOwnerData struct {
	Name               string
	ChairRegisterToken string
}

type RegisteredUserData

type RegisteredUserData struct {
	UserName       string
	FirstName      string
	LastName       string
	DateOfBirth    string
	InvitationCode string
}

type Request

type Request struct {
	// ID ベンチマーカー内部リクエストID
	ID RequestID
	// ServerID サーバー上でのリクエストID
	ServerID string
	// User リクエストしたユーザー
	User *User
	// PickupPoint 配椅子位置
	PickupPoint Coordinate
	// DestinationPoint 目的地
	DestinationPoint Coordinate
	// Discount 最大割引額
	Discount int

	// Chair 割り当てられた椅子。割り当てられるまでnil
	Chair *Chair
	// StartPoint 椅子の初期位置。割り当てられるまでnil
	StartPoint null.Value[Coordinate]

	// RequestedAt リクエストを行った時間
	RequestedAt int64
	// MatchedAt マッチングが完了した時間。割り当てられるまで0
	MatchedAt int64
	// DispatchedAt 配椅子位置についた時間。割り当てられるまで0
	DispatchedAt int64
	// PickedUpAt ピックアップされ出発された時間。割り当てられるまで0
	PickedUpAt int64
	// ArrivedAt 目的地に到着した時間。割り当てられるまで0
	ArrivedAt int64
	// CompletedAt リクエストが正常に完了した時間。割り当てられるまで0
	CompletedAt int64
	// ServerCompletedAt サーバー側で記録されている完了時間
	ServerCompletedAt time.Time

	// BenchRequestedAt ベンチがライドのリクエストを送って成功した時間
	BenchRequestedAt time.Time
	// BenchRequestAcceptTime ベンチがAcceptのリクエストを送った時間(レスポンスが帰ってきた時間ではない)
	BenchRequestAcceptTime time.Time

	// Evaluated リクエストの評価が完了しているかどうか
	Evaluated atomic.Bool
	// Paid リクエストの支払いが完了しているかどうか
	Paid atomic.Bool

	Statuses RequestStatuses
}

func (*Request) ActualDiscount

func (r *Request) ActualDiscount() int

ActualDiscount 実際に割り引いた価格

func (*Request) CalculateEvaluation

func (r *Request) CalculateEvaluation() Evaluation

CalculateEvaluation 送迎の評価値を計算する

func (*Request) Fare

func (r *Request) Fare() int

Fare ユーザーが支払う料金

func (*Request) Intervals

func (r *Request) Intervals() [3]int64

func (*Request) PartialScore

func (r *Request) PartialScore() int

func (*Request) Sales

func (r *Request) Sales() int

Sales 売り上げ

func (*Request) Score

func (r *Request) Score() int

func (*Request) SetID

func (r *Request) SetID(id RequestID)

func (*Request) String

func (r *Request) String() string

type RequestDB

type RequestDB struct {
	// contains filtered or unexported fields
}

func NewRequestDB

func NewRequestDB() *RequestDB

func (*RequestDB) Create

func (db *RequestDB) Create(req *Request) *Request

func (*RequestDB) Get

func (db *RequestDB) Get(id RequestID) *Request

func (*RequestDB) GetByServerID

func (db *RequestDB) GetByServerID(serverID string) *Request

func (*RequestDB) Iter

func (db *RequestDB) Iter() iter.Seq2[RequestID, *Request]

func (*RequestDB) Size

func (db *RequestDB) Size() int

func (*RequestDB) ToSlice

func (db *RequestDB) ToSlice() []*Request

func (*RequestDB) Values

func (db *RequestDB) Values() iter.Seq[*Request]

type RequestHistory

type RequestHistory struct {
	ID                    string
	PickupCoordinate      Coordinate
	DestinationCoordinate Coordinate
	Chair                 RequestHistoryChair
	Fare                  int
	Evaluation            int
	RequestedAt           time.Time
	CompletedAt           time.Time
}

type RequestHistoryChair

type RequestHistoryChair struct {
	ID    string
	Owner string
	Name  string
	Model string
}

type RequestID

type RequestID int

type RequestStatus

type RequestStatus int
const (
	RequestStatusMatching RequestStatus = iota
	RequestStatusDispatching
	RequestStatusDispatched
	RequestStatusCarrying
	RequestStatusArrived
	RequestStatusCompleted
)

func (RequestStatus) String

func (r RequestStatus) String() string

type RequestStatuses

type RequestStatuses struct {
	// Desired 現在の想定されるリクエストステータス
	Desired RequestStatus
	// Chair 現在椅子が認識しているステータス
	Chair RequestStatus
	// User 現在ユーザーが認識しているステータス
	User RequestStatus
	// contains filtered or unexported fields
}

func (*RequestStatuses) Get

func (s *RequestStatuses) Get() (desired, chair, user RequestStatus)

func (*RequestStatuses) Lock

func (s *RequestStatuses) Lock()

Lock DesiredのみをWrite Lockします MEMO: ロックを取らなけらばならないところ以外はとってない

func (*RequestStatuses) RLock

func (s *RequestStatuses) RLock()

RLock DesiredのみをRead Lockします MEMO: ロックを取らなけらばならないところ以外はとってない

func (*RequestStatuses) RUnlock

func (s *RequestStatuses) RUnlock()

RUnlock DesiredのみをRead Unlockします MEMO: ロックを取らなけらばならないところ以外はとってない

func (*RequestStatuses) String

func (s *RequestStatuses) String() string

func (*RequestStatuses) Unlock

func (s *RequestStatuses) Unlock()

Unlock DesiredのみをWrite Unlockします MEMO: ロックを取らなけらばならないところ以外はとってない

type SendChairCoordinateResponse

type SendChairCoordinateResponse struct {
	RecordedAt time.Time
}

type SendCreateRequestResponse

type SendCreateRequestResponse struct {
	ServerRequestID string
}

type SendEvaluationResponse

type SendEvaluationResponse struct {
	CompletedAt time.Time
}

type User

type User struct {
	// ID ベンチマーカー内部ユーザーID
	ID UserID
	// ServerID サーバー上でのユーザーID
	ServerID string
	// World Worldへの逆参照
	World *World
	// Region ユーザーが居る地域
	Region *Region
	// State ユーザーの状態
	State UserState
	// Request 進行中の配椅子・送迎リクエスト
	Request *Request
	// RegisteredData サーバーに登録されているユーザー情報
	RegisteredData RegisteredUserData
	// PaymentToken 支払いトークン
	PaymentToken string
	// RequestHistory リクエスト履歴
	RequestHistory []*Request
	// TotalEvaluation 完了したリクエストの平均評価
	TotalEvaluation int
	// Client webappへのクライアント
	Client UserClient
	// Rand 専用の乱数
	Rand *rand.Rand
	// Invited 招待されたユーザーか
	Invited bool
	// InvitingLock 招待ロック
	InvitingLock sync.Mutex
	// InvCodeUsedCount 招待コードの使用回数
	InvCodeUsedCount int
	// UnusedInvCoupons 未使用の招待クーポンの数
	UnusedInvCoupons int
	// contains filtered or unexported fields
}

func (*User) ChangeRequestStatus

func (u *User) ChangeRequestStatus(status RequestStatus, serverRequestID string, validator func() error) error

func (*User) CheckRequestHistory

func (u *User) CheckRequestHistory(ctx *Context) error

func (*User) CreateRequest

func (u *User) CreateRequest(ctx *Context) error

func (*User) Deactivate

func (u *User) Deactivate()

func (*User) GetServerID

func (u *User) GetServerID() string

func (*User) HandleNotification

func (u *User) HandleNotification(event NotificationEvent) error

func (*User) SetID

func (u *User) SetID(id UserID)

func (*User) String

func (u *User) String() string

func (*User) Tick

func (u *User) Tick(ctx *Context) error

func (*User) ValidateNotificationEvent

func (u *User) ValidateNotificationEvent(rideID string, serverSide UserNotificationEvent, ignoreChair bool) error

type UserClient

type UserClient interface {
	// SendCreateRequest サーバーにリクエスト作成を送信する
	SendCreateRequest(ctx *Context, req *Request) (*SendCreateRequestResponse, error)
	// GetRequests サーバーからリクエスト一覧を取得する
	GetRequests(ctx *Context) (*GetRequestsResponse, error)
	// GetNearbyChairs サーバーから近くの椅子の情報を取得する
	GetNearbyChairs(ctx *Context, current Coordinate, distance int) (*GetNearbyChairsResponse, error)
	// GetEstimatedFare サーバーから料金の見積もりを取る
	GetEstimatedFare(ctx *Context, pickup Coordinate, dest Coordinate) (*GetEstimatedFareResponse, error)
	// SendEvaluation サーバーに今回の送迎の評価を送信する
	SendEvaluation(ctx *Context, req *Request, score int) (*SendEvaluationResponse, error)
	// RegisterPaymentMethods サーバーにユーザーの支払い情報を登録する
	RegisterPaymentMethods(ctx *Context, user *User) error
	// ConnectUserNotificationStream ユーザー用の通知ストリームに接続する
	ConnectUserNotificationStream(ctx *Context, user *User, receiver NotificationReceiverFunc) (NotificationStream, error)
	// BrowserAccess ブラウザでアクセスしたときのリクエストを送信する
	BrowserAccess(ctx *Context, scenario benchrun.FrontendPathScenario) error
}

type UserID

type UserID int

type UserNotificationEvent

type UserNotificationEvent struct {
	Pickup      Coordinate
	Destination Coordinate
	Fare        int
	Chair       *UserNotificationEventChairPayload
}

type UserNotificationEventArrived

type UserNotificationEventArrived struct {
	ServerRequestID string
	UserNotificationEvent
	// contains filtered or unexported fields
}

type UserNotificationEventCarrying

type UserNotificationEventCarrying struct {
	ServerRequestID string
	UserNotificationEvent
	// contains filtered or unexported fields
}

type UserNotificationEventChairPayload

type UserNotificationEventChairPayload struct {
	ID    string
	Name  string
	Model string
	Stats UserNotificationEventChairStatsPayload
}

type UserNotificationEventChairStatsPayload

type UserNotificationEventChairStatsPayload struct {
	TotalRidesCount    int
	TotalEvaluationAvg float64
}

type UserNotificationEventCompleted

type UserNotificationEventCompleted struct {
	ServerRequestID string
	UserNotificationEvent
	// contains filtered or unexported fields
}

type UserNotificationEventDispatched

type UserNotificationEventDispatched struct {
	ServerRequestID string
	UserNotificationEvent
	// contains filtered or unexported fields
}

type UserNotificationEventDispatching

type UserNotificationEventDispatching struct {
	ServerRequestID string
	UserNotificationEvent
	// contains filtered or unexported fields
}

type UserNotificationEventMatching

type UserNotificationEventMatching struct {
	ServerRequestID string
	UserNotificationEvent
	// contains filtered or unexported fields
}

type UserState

type UserState int
const (
	UserStateInactive UserState = iota
	UserStatePaymentMethodsNotRegister
	UserStateActive
)

type World

type World struct {
	// Time 仮想世界開始からの経過時間
	Time int64
	// Regions 地域
	Regions []*Region
	// UserDB 全ユーザーDB
	UserDB *GenericDB[UserID, *User]
	// OwnerDB 全オーナーDB
	OwnerDB *GenericDB[OwnerID, *Owner]
	// ChairDB 全椅子DB
	ChairDB *GenericDB[ChairID, *Chair]
	// RequestDB 全リクエストDB
	RequestDB *RequestDB
	// PaymentDB 支払い結果DB
	PaymentDB *PaymentDB
	// Client webappへのクライアント
	Client WorldClient
	// RootRand ルートの乱数生成器
	RootRand *rand.Rand
	// CompletedRequestChan 完了したリクエストのチャンネル
	CompletedRequestChan chan *Request
	// ErrorCounter エラーカウンター
	ErrorCounter *ErrorCounter
	// EmptyChairs 空車椅子マップ
	EmptyChairs *concurrent.SimpleSet[*Chair]

	// TimeoutTickCount タイムアウトしたTickの累計数
	TimeoutTickCount int

	// LeavedUserCount 離脱したユーザーの数
	LeavedUserCount atomic.Int32
	// InvitedUserCount 招待されたユーザーの数
	InvitedUserCount atomic.Int32
	// NotInvitedUserCount 招待されずに登録したユーザーの数
	NotInvitedUserCount atomic.Int32
	// contains filtered or unexported fields
}

func NewWorld

func NewWorld(tickTimeout time.Duration, completedRequestChan chan *Request, client WorldClient, contestantLogger *slog.Logger) *World

func (*World) CreateChair

func (w *World) CreateChair(ctx *Context, args *CreateChairArgs) (*Chair, error)

CreateChair 仮想世界に椅子を作成する

func (*World) CreateOwner

func (w *World) CreateOwner(ctx *Context, args *CreateOwnerArgs) (*Owner, error)

CreateOwner 仮想世界に椅子のオーナーを作成する

func (*World) CreateUser

func (w *World) CreateUser(ctx *Context, args *CreateUserArgs) (*User, error)

CreateUser 仮想世界にユーザーを作成する

func (*World) Finish

func (w *World) Finish()

func (*World) PublishEvent

func (w *World) PublishEvent(e Event)

func (*World) RestTicker

func (w *World) RestTicker()

func (*World) Tick

func (w *World) Tick(ctx *Context) error

type WorldClient

type WorldClient interface {
	// RegisterUser サーバーにユーザーを登録する
	RegisterUser(ctx *Context, data *RegisterUserRequest, beforeRequest func(client UserClient) error) (*RegisterUserResponse, error)
	// RegisterOwner サーバーにオーナーを登録する
	RegisterOwner(ctx *Context, data *RegisterOwnerRequest, beforeRequest func(client OwnerClient) error) (*RegisterOwnerResponse, error)
	// RegisterChair サーバーにユーザーを登録する
	RegisterChair(ctx *Context, owner *Owner, data *RegisterChairRequest) (*RegisterChairResponse, error)
}

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL