Task background
We publish our jobs to different marketing sources. To keep track of where the particular job is published, we create
Campaign
entity in database. Campaigns
are periodically synchronized with 3rd party Ad Service.
Campaign
properties:
id
job_id
status
: one of [active, paused, deleted]external_reference
: corresponds to Ad’s ‘reference’ad_description
: text description of an Ad
Due to various types of failures (Ad Service inavailability, errors in campaign details etc.)
local Campaigns
can fall out of sync with Ad Service.
So we need a way to detect discrepancies between local and remote state.
Pre requisites
You should have sqlite installed. For example, in Ubuntu, run sudo apt-get install libsqlite3-dev
Then run bundle install
Tests
Run bundle exec rspec
How does it work
This lib implements DiscrepanciesService
that get campaigns from external JSON API(example link) and detect discrepancies between local and remote state.
The service will match local and remote campaigns by their remote reference and compare their attributes (currently state
and description
).
States are matched in the following way:
- Local
active
is equivalent to remoteenabled
; - Local
paused
is equivalent to remotedisabled
; - Local
deleted
is supposed not to have a matching remote campaign;
Service output format
DiscrepanciesService#call
will return an array with a hash for each campaign, with the attributes remote_reference
and discrepancies
.
The discrepancies
attribute is an array with discrepancies. Each discrepancy is a hash with 3 attributes: property
, remote
and local
.
High level example (with discrepancies details omitted):
[
{
remote_reference: "1",
discrepancies: [...]
},
{
remote_reference: "2",
discrepancies: [...]
}
]
When local and remote campaigns are found with no discrepant attributes the discrepancies array will be empty:
{
remote_reference: "1",
discrepancies: []
}
When local and remote campaigns are found with discrepant attributes:
{
remote_reference: "2",
discrepancies: [
{
property: "status",
remote: "disabled",
local: "active"
},
{
propery: "description",
remote: "Rails Engineer",
local: "Ruby on Rails Developer"
}
]
}
When local campaign for remote reference does not exist, the service will report discrepancy for all attributes, using nil
for local values.
{
remote_reference: "3",
discrepancies: [
{
property: "status",
remote: "disabled",
local: nil
},
{
property: "description",
remote: "Senior Rails Engineer",
local: nil
}
]
}
When remote campaign is not found, and local campaign status is not 'deleted'
, then the service will report discrepancy for all attributes, using nil
for remote values.
{
remote_reference: "4",
discrepancies: [
{
property: "status",
remote: nil,
local: "paused"
},
{
property: "description",
remote: nil,
local: "Junior Rails Engineer"
}
]
}