---
# System prepended metadata

title: Untitled

---

##  Summary

 
To understand how event messaging work at first read about [Transaction Outbox Pattern](https://microservices.io/patterns/data/transactional-outbox.html).
We use this pattern to send events. [Here you can find event module](http://gitlab.pandadoc.com/product/gwpy-core/-/tree/master/pandadoc/apps/events)

Event module implements this pattern this way:

![](https://i.imgur.com/eglXGBV.png)

1. Generate new table record:

```python=
from event.signals import my_library as events

events.event_name.send(sender=sender, **arguments)
```

 2-3. процесс который читает и паблишит в кафку

```python=
class Command(ProduceWorker):
    event_model = MyLibraryEventModel

    event_endpoint = endpoints.MY_LIBRARY_EVENTS

    lock_id = 998015830  # use any unique integer identifier

    db_query_limit = settings.PRODUCER_BATCH_SIZE

    sleep_timeout = settings.PRODUCER_SLEEP_TIMEOUT

    sequence_number_offset = settings.PRODUCER_SEQUENCE_NUMBER_OFFSET_DOCUMENT_EVENTS

    def get_event_key(self, prepared_event):
        return prepared_event["event_data"]["document_id"]

... #todo describe worker there
```


regular-document.service как OrderService 
на пустую доку ссылка тут

![](https://i.imgur.com/ivURLA5.png)



## How to add new event model


1. At first you need to create event with all type of events you want to listen to.`events/events.py`

```python=
@enum.unique
class MyLibraryEvent 
  EVENT_NAME = "event_name"
```

2. After you need to describe event model   `events/models.py`

```python=
class MyLibraryEvent(AbstractEvent) 
   """ Model to handle document related events. """

   event_name = StringEnumField(
       events.MyLibraryEvent,
       max_length: 255,
       help_text: "Event type (value of MyLibraryEvent enum)"
       )    
```
   
   
## How to add a new type of events


New type of event consist from *schema*, *signal* and *receiver*. First of all check if you have the event name described in event enum `events/events.py`

1. Create *signal* and provide arguments: 

```python=
from django.core.signals import Signal

event_name = Signal(providing_args=("arg1", "arg2"))
```

2. Create *schema* and describe arguments:

```python=
class EventNameData:
   arg1: any 
   arg2: any 
```

3. Create *receiver* for event type:

```python=
@receiver(
    signals.my_library.event_name
    event_name=MyLibraryEvent.EVENT_NAME,
    event_schema
)
def event_name(sender, *, arg1, arg2) 
    # put arguments to data
    return data
    
```

After you can send event everywhere you want 

```python=
from event.signals import my_library as events

events.event_name.send(sender=sender, **arguments)
```


## Setup events

1. You need to add new event endpoint `events/endpoints.py`

```python=
MY_LIBRARY_EVENTS = pdms.Endpoint('gwpy-core', 'my_name_events')
```

2. After we need to create worker which will produce events: 

```python=
class Command(ProduceWorker)
    event_model = MyLibraryEventModel

... #todo describe worker there

```



*==todo написать как все стартануть локально==*
*==todo написать как тестировать==*

We use decorator for connecting event receivers to signals.For each event receiver you must specify:

* model from `events.models` module which will be used to store event data;
* unique name from `events.constants` module;
* schema from `events.schemas` module for event data validation.

All events models realized `AbstractEvent`. It is base abstract model to support common producer flow (MainDB -> Kafka).
    Each inherited model will be dispatched to dedicated Kafka topic by producer. 
Each event has `sequence_number`(auto increment sequence field) to support consistent ordering

Producer `ProduceWorker` publishes events to kafka.