eventstore-0.9.1.0: EventStore TCP Client

Copyright(C) 2014 Yorick Laupa
License(see the file LICENSE)
MaintainerYorick Laupa <yo.eight@gmail.com>
Stabilityprovisional
Portabilitynon-portable
Safe HaskellNone
LanguageHaskell2010

Database.EventStore

Contents

Description

 

Synopsis

Connection

data Connection Source

Represents a connection to a single EventStore node.

data ConnectionException Source

Type of connection issue that can arise during the communication with the server.

Constructors

MaxAttemptConnectionReached HostName Int Int

The max reconnection attempt threshold has been reached. Holds a HostName, the port used and the given threshold.

ClosedConnection

Use of a close Connection.

data ServerConnectionError Source

Raised when the server responded in an unexpected way.

Constructors

WrongPackageFraming

TCP package sent by the server had a wrong framing.

PackageParsingError String

Server sent a malformed TCP package.

data Credentials Source

Holds login and password information.

data Retry Source

Represents reconnection strategy.

atMost :: Int -> Retry Source

Indicates how many times we should try to reconnect to the server. A value less than or equal to 0 means no retry.

keepRetrying :: Retry Source

Indicates we should try to reconnect to the server until the end of the Universe.

credentials Source

Arguments

:: ByteString

Login

-> ByteString

Password

-> Credentials 

Creates a Credentials given a login and a password.

defaultSettings :: Settings Source

Default global settings.

connect Source

Arguments

:: Settings 
-> String

HostName

-> Int

Port

-> IO Connection 

Creates a new Connection to a single node. It maintains a full duplex connection to the EventStore. An EventStore Connection operates quite differently than say a SQL connection. Normally when you use an EventStore connection you want to keep the connection open for a much longer of time than when you use a SQL connection.

Another difference is that with the EventStore Connection all operations are handled in a full async manner (even if you call the synchronous behaviors). Many threads can use an EvenStore Connection at the same time or a single thread can make many asynchronous requests. To get the most performance out of the connection it is generally recommended to use it in this way.

shutdown :: Connection -> IO () Source

Asynchronously closes the Connection.

waitTillClosed :: Connection -> IO () Source

Waits the Connection to be closed.

Event

data Event Source

Contains event information like its type and data. Only used for write queries.

data EventData Source

Holds event data.

createEvent Source

Arguments

:: Text

Event type

-> Maybe UUID

Event ID, generated if Nothing

-> EventData

Event data

-> Event 

Create an Event meant to be persisted.

withJson :: ToJSON a => a -> EventData Source

Creates a event using JSON format

withJsonAndMetadata :: (ToJSON a, ToJSON b) => a -> b -> EventData Source

Create a event with metadata using JSON format

Read Operations

data StreamMetadataResult Source

Represents stream metadata as a series of properties for system data and a StreamMetadata object for user metadata.

Constructors

StreamMetadataResult 

Fields

streamMetaResultStream :: !Text

The name of the stream.

streamMetaResultVersion :: !Int32

The version of the metadata format.

streamMetaResultData :: !StreamMetadata

A StreamMetadata containing user-specified metadata.

NotFoundStreamMetadataResult

When the stream is either not found or 'no stream'.

Fields

streamMetaResultStream :: !Text

The name of the stream.

DeletedStreamMetadataResult

When the stream is soft-deleted.

Fields

streamMetaResultStream :: !Text

The name of the stream.

readEvent Source

Arguments

:: Connection 
-> Text

Stream name

-> Int32

Event number

-> Bool

Resolve Link Tos

-> IO (Async (ReadResult RegularStream ReadEvent)) 

Reads a single event from given stream.

readAllEventsBackward Source

Arguments

:: Connection 
-> Position 
-> Int32

Batch size

-> Bool

Resolve Link Tos

-> IO (Async AllSlice) 

Reads events from the $all stream backward

readAllEventsForward Source

Arguments

:: Connection 
-> Position 
-> Int32

Batch size

-> Bool

Resolve Link Tos

-> IO (Async AllSlice) 

Reads events from the $all stream forward.

readStreamEventsBackward Source

Arguments

:: Connection 
-> Text

Stream name

-> Int32

From event number

-> Int32

Batch size

-> Bool

Resolve Link Tos

-> IO (Async (ReadResult RegularStream StreamSlice)) 

Reads events from a given stream backward.

readStreamEventsForward Source

Arguments

:: Connection 
-> Text

Stream name

-> Int32

From event number

-> Int32

Batch size

-> Bool

Resolve Link Tos

-> IO (Async (ReadResult RegularStream StreamSlice)) 

Reads events from a given stream forward.

getStreamMetadata :: Connection -> Text -> IO (Async StreamMetadataResult) Source

Asynchronously gets the metadata of a stream.

Write Operations

data StreamACL Source

Represents an access control list for a stream.

Constructors

StreamACL 

Fields

streamACLReadRoles :: ![Text]

Roles and users permitted to read the stream.

streamACLWriteRoles :: ![Text]

Roles and users permitted to write to the stream.

streamACLDeleteRoles :: ![Text]

Roles and users permitted to delete to the stream.

streamACLMetaReadRoles :: ![Text]

Roles and users permitted to read stream metadata.

streamACLMetaWriteRoles :: ![Text]

Roles and users permitted to write stream metadata.

data StreamMetadata Source

Represents stream metadata with strongly typed properties for system values and a dictionary-like interface for custom values.

Constructors

StreamMetadata 

Fields

streamMetadataMaxCount :: !(Maybe Int32)

The maximum number of events allowed in the stream.

streamMetadataMaxAge :: !(Maybe TimeSpan)

The maximum age of events allowed in the stream.

streamMetadataTruncateBefore :: !(Maybe Int32)

The event number from which previous events can be scavenged. This is used to implement soft-deletion of streams.

streamMetadataCacheControl :: !(Maybe TimeSpan)

The amount of time for which the stream head is cachable.

streamMetadataACL :: !StreamACL

The access control list for the stream.

streamMetadataCustom :: !Object

An enumerable of key-value pairs of keys to JSON text for user-provider metadata.

getCustomPropertyValue :: StreamMetadata -> Text -> Maybe Value Source

Gets a custom property value from metadata.

getCustomProperty :: FromJSON a => StreamMetadata -> Text -> Maybe a Source

Get a custom property value from metadata.

emptyStreamACL :: StreamACL Source

StreamACL with no role or users whatsoever.

deleteStream Source

Arguments

:: Connection 
-> Text

Stream name

-> ExpectedVersion 
-> Maybe Bool

Hard delete

-> IO (Async DeleteResult) 

Deletes given stream.

sendEvent Source

Arguments

:: Connection 
-> Text

Stream name

-> ExpectedVersion 
-> Event 
-> IO (Async WriteResult) 

Sends a single Event to given stream.

sendEvents Source

Arguments

:: Connection 
-> Text

Stream name

-> ExpectedVersion 
-> [Event] 
-> IO (Async WriteResult) 

Sends a list of Event to given stream.

setStreamMetadata :: Connection -> Text -> ExpectedVersion -> StreamMetadata -> IO (Async WriteResult) Source

Asynchronously sets the metadata for a stream.

Builder

type Builder a = Endo a Source

Allows to build a structure using Monoid functions.

Stream ACL Builder

setReadRoles :: [Text] -> StreamACLBuilder Source

Sets role names with read permission for the stream.

setReadRole :: Text -> StreamACLBuilder Source

Sets a single role name with read permission for the stream.

setWriteRoles :: [Text] -> StreamACLBuilder Source

Sets role names with write permission for the stream.

setWriteRole :: Text -> StreamACLBuilder Source

Sets a single role name with write permission for the stream.

setDeleteRoles :: [Text] -> StreamACLBuilder Source

Sets role names with delete permission for the stream.

setDeleteRole :: Text -> StreamACLBuilder Source

Sets a single role name with delete permission for the stream.

setMetaReadRoles :: [Text] -> StreamACLBuilder Source

Sets role names with metadata read permission for the stream.

setMetaReadRole :: Text -> StreamACLBuilder Source

Sets a single role name with metadata read permission for the stream.

setMetaWriteRoles :: [Text] -> StreamACLBuilder Source

Sets role names with metadata write permission for the stream.

setMetaWriteRole :: Text -> StreamACLBuilder Source

Sets a single role name with metadata write permission for the stream.

Stream Metadata Builder

setMaxCount :: Int32 -> StreamMetadataBuilder Source

Sets the maximum number of events allowed in the stream.

setMaxAge :: TimeSpan -> StreamMetadataBuilder Source

Sets the maximum age of events allowed in the stream.

setTruncateBefore :: Int32 -> StreamMetadataBuilder Source

Sets the event number from which previous events can be scavenged.

setCacheControl :: TimeSpan -> StreamMetadataBuilder Source

Sets the amount of time for which the stream head is cachable.

setACL :: StreamACL -> StreamMetadataBuilder Source

Overwrites any previous StreamACL by the given one in a StreamMetadataBuilder.

setCustomProperty :: ToJSON a => Text -> a -> StreamMetadataBuilder Source

Sets a custom metadata property.

TimeSpan

data TimeSpan Source

.NET TimeSpan: Represents a time interval.

timeSpanTicks :: Int64 -> TimeSpan Source

Initializes a new instance of the TimeSpan structure to the specified number of ticks.

timeSpanHoursMinsSecs :: Int64 -> Int64 -> Int64 -> TimeSpan Source

Initializes a new instance of the TimeSpan structure to a specified number of hours, minutes, and seconds.

timeSpanDaysHoursMinsSecs :: Int64 -> Int64 -> Int64 -> Int64 -> TimeSpan Source

Initializes a new instance of the TimeSpan structure to a specified number of days, hours, minutes, and seconds.

timeSpanDaysHoursMinsSecsMillis :: Int64 -> Int64 -> Int64 -> Int64 -> Int64 -> TimeSpan Source

Initializes a new instance of the TimeSpan structure to a specified number of days, hours, minutes, seconds, and milliseconds.

timeSpanGetTicks :: TimeSpan -> Int64 Source

Gets the number of ticks that represent the value of the current TimeSpan structure.

timeSpanGetDays :: TimeSpan -> Int64 Source

Gets the days component of the time interval represented by the current TimeSpan structure.

timeSpanGetHours :: TimeSpan -> Int64 Source

Gets the hours component of the time interval represented by the current TimeSpan structure.

timeSpanGetMinutes :: TimeSpan -> Int64 Source

Gets the minutes component of the time interval represented by the current TimeSpan structure.

timeSpanGetSeconds :: TimeSpan -> Int64 Source

Gets the seconds component of the time interval represented by the current TimeSpan structure.

timeSpanGetMillis :: TimeSpan -> Int64 Source

Gets the milliseconds component of the time interval represented by the current TimeSpan structure.

timeSpanFromSeconds :: Double -> TimeSpan Source

Returns a TimeSpan that represents a specified number of seconds, where the specification is accurate to the nearest millisecond.

timeSpanFromMinutes :: Double -> TimeSpan Source

Returns a TimeSpan that represents a specified number of minutes, where the specification is accurate to the nearest millisecond.

timeSpanFromHours :: Double -> TimeSpan Source

Returns a TimeSpan that represents a specified number of hours, where the specification is accurate to the nearest millisecond.

timeSpanFromDays :: Double -> TimeSpan Source

Returns a TimeSpan that represents a specified number of days, where the specification is accurate to the nearest millisecond.

timeSpanTotalMillis :: TimeSpan -> Int64 Source

Gets the value of the current TimeSpan structure expressed in whole and fractional milliseconds.

Transaction

data Transaction Source

Represents a multi-request transaction with the EventStore.

startTransaction Source

Arguments

:: Connection 
-> Text

Stream name

-> ExpectedVersion 
-> IO (Async Transaction) 

Starts a transaction on given stream.

transactionCommit :: Transaction -> IO (Async WriteResult) Source

Asynchronously commits this transaction.

transactionRollback :: Transaction -> IO () Source

There isn't such of thing in EventStore parlance. Basically, if you want to rollback, you just have to not transactionCommit a Transaction.

transactionWrite :: Transaction -> [Event] -> IO (Async ()) Source

Asynchronously writes to a transaction in the EventStore.

Subscription

data SubscriptionClosed Source

This exception is raised when the user tries to get the next event from a Subscription that is already closed.

data Subscription a Source

It's possible to subscribe to a stream and be notified when new events are written to that stream. There are three types of subscription which are available, all of which can be useful in different situations.

data Running Source

Represents a running subscription. Gathers useful information.

Constructors

RunningReg UUID Text Bool Int64 (Maybe Int32)

Related regular subscription. In order of appearance:

  • Subscription id.
  • Stream name.
  • Resolve Link TOS.
  • Last commit position.
  • Last event number.
RunningPersist UUID Text Text Int32 Text Int64 (Maybe Int32)

Related to persistent subscription. In order of appearance:

  • Subscription id.
  • Group name.
  • Stream name.
  • Buffer size.
  • Persistence subscription id.
  • Last commit position.
  • Last event number.

Instances

data SubDropReason Source

Indicates why a subscription has been dropped.

Constructors

SubUnsubscribed

Subscription connection has been closed by the user.

SubAccessDenied

The current user is not allowed to operate on the supplied stream.

SubNotFound

Given stream name doesn't exist.

SubPersistDeleted

Given stream is deleted.

SubAborted

Occurs when the user shutdown the connection from the server or if the connection to the server is no longer possible.

Volatile Subscription

data Regular Source

Also referred as volatile subscription. For example, if a stream has 100 events in it when a subscriber connects, the subscriber can expect to see event number 101 onwards until the time the subscription is closed or dropped.

subscribe Source

Arguments

:: Connection 
-> Text

Stream name

-> Bool

Resolve Link Tos

-> IO (Subscription Regular) 

Subcribes to given stream.

subscribeToAll Source

Arguments

:: Connection 
-> Bool

Resolve Link Tos

-> IO (Subscription Regular) 

Subcribes to $all stream.

getSubId :: Subscription a -> IO SubscriptionId Source

Gets the ID of the subscription.

getSubStream :: Subscription a -> Text Source

Gets the subscription stream name.

isSubscribedToAll :: Subscription a -> Bool Source

If the subscription is on the $all stream.

unsubscribe :: Subscription a -> IO () Source

Asynchronously unsubscribe from the the stream.

nextEvent :: Subscription a -> IO ResolvedEvent Source

Awaits for the next event.

getSubResolveLinkTos :: Subscription Regular -> Bool Source

Determines whether or not any link events encontered in the stream will be resolved.

getSubLastCommitPos :: Subscription a -> IO Int64 Source

The last commit position seen on the subscription (if this a subscription to $all stream).

getSubLastEventNumber :: Subscription a -> IO (Maybe Int32) Source

The last event number seen on the subscription (if this is a subscription to a single stream).

Catch-up Subscription

data Catchup Source

This kind of subscription specifies a starting point, in the form of an event number or transaction file position. The given function will be called for events from the starting point until the end of the stream, and then for subsequently written events.

For example, if a starting point of 50 is specified when a stream has 100 events in it, the subscriber can expect to see events 51 through 100, and then any events subsequently written until such time as the subscription is dropped or closed.

subscribeFrom Source

Arguments

:: Connection 
-> Text

Stream name

-> Bool

Resolve Link Tos

-> Maybe Int32

Last checkpoint

-> Maybe Int32

Batch size

-> IO (Subscription Catchup) 

Subscribes to given stream. If last checkpoint is defined, this will readStreamEventsForward from that event number, otherwise from the beginning. Once last stream event reached up, a subscription request will be sent using subscribe.

subscribeToAllFrom Source

Arguments

:: Connection 
-> Bool

Resolve Link Tos

-> Maybe Position

Last checkpoint

-> Maybe Int32

Batch size

-> IO (Subscription Catchup) 

Same as subscribeFrom but applied to $all stream.

waitTillCatchup :: Subscription Catchup -> IO () Source

Waits until CatchupSubscription subscription catch-up its stream.

Persistent Subscription

data Persistent Source

The server remembers the state of the subscription. This allows for many different modes of operations compared to a regular or catchup subscription where the client holds the subscription state. (Need EventStore >= v3.1.0).

data PersistentSubscriptionSettings Source

Gathers every persistent subscription property.

Constructors

PersistentSubscriptionSettings 

Fields

psSettingsResolveLinkTos :: !Bool

Whether or not the persistent subscription should resolve linkTo events to their linked events.

psSettingsStartFrom :: !Int32

Where the subscription should start from (position).

psSettingsExtraStats :: !Bool

Whether or not in depth latency statistics should be tracked on this subscription.

psSettingsMsgTimeout :: !TimeSpan

The amount of time after which a message should be considered to be timeout and retried.

psSettingsMaxRetryCount :: !Int32

The maximum number of retries (due to timeout) before a message get considered to be parked.

psSettingsLiveBufSize :: !Int32

The size of the buffer listening to live messages as they happen.

psSettingsReadBatchSize :: !Int32

The number of events read at a time when paging in history.

psSettingsHistoryBufSize :: !Int32

The number of events to cache when paging through history.

psSettingsCheckPointAfter :: !TimeSpan

The amount of time to try checkpoint after.

psSettingsMinCheckPointCount :: !Int32

The minimum number of messages to checkpoint.

psSettingsMaxCheckPointCount :: !Int32

The maximum number of message to checkpoint. If this number is reached, a checkpoint will be forced.

psSettingsMaxSubsCount :: !Int32

The maximum number of subscribers allowed.

psSettingsNamedConsumerStrategy :: !SystemConsumerStrategy

The strategy to use for distributing events to client consumers.

data SystemConsumerStrategy Source

System supported consumer strategies for use with persistent subscriptions.

Constructors

DispatchToSingle

Distributes events to a single client until it is full. Then round robin to the next client.

RoundRobin

Distributes events to each client in a round robin fashion.

data NakAction Source

Gathers every possible Nak actions.

data PersistActionException Source

Enumerates all persistent action exceptions.

Constructors

PersistActionFail

The action failed.

PersistActionAlreadyExist

Happens when creating a persistent subscription on a stream with a group name already taken.

PersistActionDoesNotExist

An operation tried to do something on a persistent subscription or a stream that don't exist.

PersistActionAccessDenied

The current user is not allowed to operate on the supplied stream or persistent subscription.

PersistActionAborted

That action has been aborted because the user shutdown the connection to the server or the connection to the server is no longer possible.

acknowledge :: Subscription Persistent -> ResolvedEvent -> IO () Source

Acknowledges that ResolvedEvent has been successfully processed.

acknowledgeEvents :: Subscription Persistent -> [ResolvedEvent] -> IO () Source

Acknowledges those ResolvedEvents have been successfully processed.

failed :: Subscription Persistent -> ResolvedEvent -> NakAction -> Maybe Text -> IO () Source

Mark a message that has failed processing. The server will take action based upon the action parameter.

eventsFailed :: Subscription Persistent -> [ResolvedEvent] -> NakAction -> Maybe Text -> IO () Source

Mark messages that have failed processing. The server will take action based upon the action parameter.

notifyEventsProcessed :: Subscription Persistent -> [UUID] -> IO () Source

Acknowledges those event ids have been successfully processed.

notifyEventsFailed :: Subscription Persistent -> NakAction -> Maybe Text -> [UUID] -> IO () Source

Acknowledges those event ids have failed to be processed successfully.

defaultPersistentSubscriptionSettings :: PersistentSubscriptionSettings Source

System default persistent subscription settings.

createPersistentSubscription :: Connection -> Text -> Text -> PersistentSubscriptionSettings -> IO (Async (Maybe PersistActionException)) Source

Asynchronously create a persistent subscription group on a stream.

updatePersistentSubscription :: Connection -> Text -> Text -> PersistentSubscriptionSettings -> IO (Async (Maybe PersistActionException)) Source

Asynchronously update a persistent subscription group on a stream.

deletePersistentSubscription :: Connection -> Text -> Text -> IO (Async (Maybe PersistActionException)) Source

Asynchronously delete a persistent subscription group on a stream.

connectToPersistentSubscription :: Connection -> Text -> Text -> Int32 -> IO (Subscription Persistent) Source

Asynchronously connect to a persistent subscription given a group on a stream.

Results

class Slice a where Source

Gathers common slice operations.

Associated Types

type Loc a Source

Methods

sliceEvents :: a -> [ResolvedEvent] Source

Gets slice's ResolvedEvents.

sliceDirection :: a -> ReadDirection Source

Gets slice's reading direction.

sliceEOS :: a -> Bool Source

If the slice reaches the end of the stream.

sliceFrom :: a -> Loc a Source

Gets the starting location of this slice.

sliceNext :: a -> Loc a Source

Gets the next location of this slice.

data AllSlice Source

Represents a slice of the $all stream.

newtype DeleteResult Source

Returned after deleting a stream. Position of the write.

Constructors

DeleteResult Position 

data WriteResult Source

Returned after writing to a stream.

Constructors

WriteResult 

Fields

writeNextExpectedVersion :: !Int32

Next expected version of the stream.

writePosition :: !Position

Position of the write.

data ReadResult :: StreamType -> * -> * where Source

Enumeration detailing the possible outcomes of reading a stream.

data RecordedEvent Source

Represents a previously written event.

Constructors

RecordedEvent 

Fields

recordedEventStreamId :: !Text

The event stream that this event belongs to.

recordedEventId :: !UUID

Unique identifier representing this event.

recordedEventNumber :: !Int32

Number of this event in the stream.

recordedEventType :: !Text

Type of this event.

recordedEventData :: !ByteString

Representing the data of this event.

recordedEventMetadata :: !(Maybe ByteString)

Representing the metadada associated with this event.

recordedEventIsJson :: !Bool

Indicates whether the content is internally marked as json.

recordedEventCreated :: !(Maybe UTCTime)

Representing when this event was created in the system.

data ReadEvent Source

Represents the result of looking up a specific event number from a stream.

Instances

data StreamType Source

A stream can either point to $all or a regular one.

Constructors

All 
RegularStream 

data Position Source

A structure referring to a potential logical record position in the EventStore transaction file.

Constructors

Position 

Fields

positionCommit :: !Int64

Commit position of the record

positionPrepare :: !Int64

Prepare position of the record

data ReadDirection Source

Represents the direction of read operation (both from $all an usual streams).

Constructors

Forward

From beginning to end

Backward

From end to beginning

data ResolvedEvent Source

A structure representing a single event or an resolved link event.

Constructors

ResolvedEvent 

Fields

resolvedEventRecord :: !(Maybe RecordedEvent)

The event, or the resolved link event if this ResolvedEvent is a link event.

resolvedEventLink :: !(Maybe RecordedEvent)

The link event if this ResolvedEvent is a link event.

resolvedEventPosition :: !(Maybe Position)

Possible Position of that event.

data OperationError Source

Operation exception that can occurs on an operation response.

Constructors

WrongExpectedVersion Text ExpectedVersion

Stream and Expected Version

StreamDeleted Text

Stream

InvalidTransaction 
AccessDenied StreamName

Stream

InvalidServerResponse Word8 Word8

Expected, Found

ProtobufDecodingError String 
ServerError (Maybe Text)

Reason

InvalidOperation Text

Invalid operation state. If happens, it's a driver bug.

Aborted

Occurs when the user asked to close the connection or if the connection can't reconnect anymore.

data StreamName Source

Represents a regular stream name or $all stream.

Constructors

StreamName Text 
AllStream 

isEventResolvedLink :: ResolvedEvent -> Bool Source

Indicates whether this ResolvedEvent is a resolved link event.

resolvedEventOriginal :: ResolvedEvent -> RecordedEvent Source

Returns the event that was read or which triggered the subscription.

If this ResolvedEvent represents a link event, the link will be the original event, otherwise it will be the event.

resolvedEventDataAsJson :: FromJSON a => ResolvedEvent -> Maybe a Source

Tries to desarialize resolvedEventOriginal data as JSON.

resolvedEventOriginalStreamId :: ResolvedEvent -> Text Source

The stream name of the original event.

resolvedEventOriginalId :: ResolvedEvent -> UUID Source

The ID of the original event.

recordedEventDataAsJson :: FromJSON a => RecordedEvent -> Maybe a Source

Tries to parse JSON object from the given RecordedEvent.

positionStart :: Position Source

Representing the start of the transaction file.

positionEnd :: Position Source

Representing the end of the transaction file.

Misc

data DropReason Source

Represents the reason subscription drop happened.

data ExpectedVersion Source

Constants used for expected version control.

The use of expected version can be a bit tricky especially when discussing idempotency assurances given by the EventStore.

The EventStore will assure idempotency for all operations using any value in ExpectedVersion except for anyStream. When using anyStream the EventStore will do its best to assure idempotency but will not guarantee idempotency.

anyVersion :: ExpectedVersion Source

This write should not conflict with anything and should always succeed.

noStreamVersion :: ExpectedVersion Source

The stream being written to should not yet exist. If it does exist treat that as a concurrency problem.

emptyStreamVersion :: ExpectedVersion Source

The stream should exist and should be empty. If it does not exist or is not empty, treat that as a concurrency problem.

exactEventVersion :: Int32 -> ExpectedVersion Source

States that the last event written to the stream should have a sequence number matching your expected value.

Re-export

(<>) :: Monoid m => m -> m -> m infixr 6

An infix synonym for mappend.

Since: 4.5.0.0