---
# System prepended metadata

title: Gfeed architecture and formatting updates

---

# Gfeed architecture and formatting updates
 
## Event based feed updates
* Move incremental update logic out of gfood and over to gfeed
* Consume ShopCMS and menu service rabbitmq messages and update feeds based on that
* This facilitates removing sidekiq jobs 
* Change nightly feed generation to only change the updated_at timestamp

## Change all JSON over to the new, cleaner v2 format
* Changing to v2 should cut down on errors due to menu being too big, but we should also consider breaking up large menus into several files. 
* Add error handling and reporting for common feed errors reported by Google, like `hasMenuItem missing` etc. 
 
 
 # Research
 
 ## Event queues and exchanges
 * [Available RabbitMQ resources](https://github.com/slicelife/shop-cms/blob/main/.gitlab-ci.yml#L116) listed in shop-cms
 * Shop CMS Publishing jobs are [here](https://github.com/slicelife/shop-cms/tree/main/jobs)
 * Menu and shop cms listen to the shop exchange, so gfeed should probably listen to the shop and menu exchanges.

## Questions
* Incremental updates: Does it matter to Google if we update a partial entity or if we update the whole doc? 
* Which exchanges/channels are pertinent? Are there federated exchanges that might have all the things?


# Potential solutions

## Incremental updates
We should be able to replace the feed update trigger (Sidekiq; runs on 5 minute interval) with a listener that ingests messages from the `shop` and `menu` RabbitMQ exchanges. We can decide on qualifying events that should trigger a rewrite of the entity. This rewrite will use the same mechanism as for regular feed generation, i.e. a request to Shop CMS and a rewrite of the entity doc. The new entity doc will theen be published via the GFO incremenetal update endpoint.

## Nightly feed generation
This can stay the same for now (ShopCMS requests at specific time at night). After the incremental update change we might be able to just update the timestamp on our entity docs, since any updates should already have been handled by the event triggered updates.

## Shop/Menu listeners
* differentiate between updates and deletes via shop event params: `google_platform_enabled`, `disabled` and `status`
* does the shop have a doc already? then we need to either update or delete. No doc + disabled => do nothing
* checking = check sitemap.xml? GfeedRecord already does this in `disable_field` method
* admin shop presenter needs `google_platform_enabled` added
* First iteration: only use messages as triggers. Every message will trigger update/delete and will get new data fomr shop cms endpoint
* Second iteration: optimize by using message data to update hence avoid request to shop cms/menu service
* Exchanges/channels to listen to:
```
- SHOP_RABBITMQ_EXCHANGE_NAME_CUISINES=${SHOP_RABBITMQ_EXCHANGE_NAME_CUISINES:-cuisines}
- SHOP_RABBITMQ_EXCHANGE_NAME_HOURS=${SHOP_RABBITMQ_EXCHANGE_NAME_HOURS:-shop.hours}
- SHOP_RABBITMQ_EXCHANGE_NAME_SCHEDULES=${SHOP_RABBITMQ_EXCHANGE_NAME_SCHEDULES:-shop.schedules}
- SHOP_RABBITMQ_EXCHANGE_NAME_SHOPS=${SHOP_RABBITMQ_EXCHANGE_NAME_SHOPS:-shop}
- SHOP_RABBITMQ_EXCHANGE_NAME_FEES=${SHOP_RABBITMQ_EXCHANGE_NAME_FEES:-shop.fees}
- SHOP_RABBITMQ_EXCHANGE_NAME_PHOTOS=${SHOP_RABBITMQ_EXCHANGE_NAME_PHOTOS:-shop.photos}
- menu exchange
```

## TODO
- [ ] Move current incremental updates logic to gfeed. Gfood still kicks off the update, but gfeed finalizes transaction. I.e. move `Gfeed::IncrementalUpdateQueuerJob` and `Gfeed::IncrementalDeleteQueuerJob` 
- [ ] Protoype the listeners in gfeed. Logging only, feature branch only (for now). This will help us determine which exchanges to listen to for most efficient updates. 