<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom"><channel><title>Jenkins on Jonathan Franklin</title><link>https://jonnie.github.io/tags/jenkins/</link><description>Recent content in Jenkins on Jonathan Franklin</description><generator>Hugo</generator><language>en</language><lastBuildDate>Fri, 16 Jul 2021 00:00:00 +0000</lastBuildDate><atom:link href="https://jonnie.github.io/tags/jenkins/index.xml" rel="self" type="application/rss+xml"/><item><title>Multi-Source Product Search API</title><link>https://jonnie.github.io/work/product-search-api/</link><pubDate>Fri, 16 Jul 2021 00:00:00 +0000</pubDate><guid>https://jonnie.github.io/work/product-search-api/</guid><description>&lt;h2 id="problem"&gt;Problem&lt;/h2&gt;&#10;&lt;p&gt;Pricesearcher&amp;rsquo;s website, browser extension and external integrations needed product data from both the company&amp;rsquo;s Elasticsearch index and third-party providers. Combining those sources meant dealing with different response formats, provider latency and client ranking requirements. The API also needed clearer boundaries between the interfaces used by different clients.&lt;/p&gt;&#10;&lt;h2 id="architecture"&gt;Architecture&lt;/h2&gt;&#10;&lt;p&gt;The Python/Flask API combined the internal Elasticsearch index with Amazon, Yahoo and Kelkoo. Third-party requests ran asynchronously and provider failures were handled separately. Redis with RediSearch supported filtering, sorting and facets over cached results. Web, browser-extension, external-client and core APIs ran as separate deployments with their own OpenAPI specifications.&lt;/p&gt;</description></item><item><title>Product Catalog Pipeline: Feeds to Products</title><link>https://jonnie.github.io/work/product-catalog-pipeline/</link><pubDate>Thu, 10 Dec 2020 00:00:00 +0000</pubDate><guid>https://jonnie.github.io/work/product-catalog-pipeline/</guid><description>&lt;h2 id="problem"&gt;Problem&lt;/h2&gt;&#10;&lt;p&gt;Pricesearcher needed to turn merchant feeds into a catalogue suitable for price comparison. Downloaded listings had to be normalised, assigned to the correct market and currency, and combined with reference data before indexing. Expansion into additional countries also required changes to feed processing, catalogue seeding and scheduling.&lt;/p&gt;&#10;&lt;h2 id="architecture"&gt;Architecture&lt;/h2&gt;&#10;&lt;p&gt;The ingestion stage processed merchant feeds into Parquet. A Spark product builder joined them with warehouse price history, categories, translated brands, linked product IDs and image-quality data, then supplied the &lt;a href="https://jonnie.github.io/work/search-index-pipeline/"&gt;search index pipeline&lt;/a&gt;. Country-specific processing and schedules ran through the same flow.&lt;/p&gt;</description></item></channel></rss>