Skip to content

Commit

Permalink
[frontend] Add FeatureFlag Provider to client side, add http fault fi…
Browse files Browse the repository at this point in the history
…lter to envoy, add slowloading featureflag
  • Loading branch information
klucsik committed Apr 11, 2024
1 parent 39e2f7e commit 4636590
Show file tree
Hide file tree
Showing 9 changed files with 327 additions and 32 deletions.
2 changes: 2 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,8 @@ the release.
([#1519](https://github.com/open-telemetry/opentelemetry-demo/pull/1519))
* [flagd] export flagd traces to otel collector
([#1522](https://github.com/open-telemetry/opentelemetry-demo/pull/1522))
* [frontend] Slowloading of images based on imageSlowLoad flag
([#1515](https://github.com/open-telemetry/opentelemetry-demo/pull/1486))

## 1.9.0

Expand Down
2 changes: 2 additions & 0 deletions docker-compose.minimal.yml
Original file line number Diff line number Diff line change
Expand Up @@ -210,6 +210,8 @@ services:
- PUBLIC_OTEL_EXPORTER_OTLP_TRACES_ENDPOINT
- OTEL_EXPORTER_OTLP_METRICS_TEMPORALITY_PREFERENCE
- WEB_OTEL_SERVICE_NAME=frontend-web
- FLAGD_HOST
- FLAGD_PORT
depends_on:
adservice:
condition: service_started
Expand Down
8 changes: 7 additions & 1 deletion docker-compose.yml
Original file line number Diff line number Diff line change
Expand Up @@ -229,7 +229,7 @@ services:
"file:./etc/flagd/demo.flagd.json"
]
ports:
- 8013
- "${FLAGD_PORT}"
volumes:
- ./src/flagd:/etc/flagd
logging:
Expand Down Expand Up @@ -298,6 +298,8 @@ services:
- OTEL_EXPORTER_OTLP_METRICS_TEMPORALITY_PREFERENCE
- WEB_OTEL_SERVICE_NAME=frontend-web
- OTEL_COLLECTOR_HOST
- FLAGD_HOST
- FLAGD_PORT
depends_on:
adservice:
condition: service_started
Expand All @@ -319,6 +321,8 @@ services:
condition: service_started
imageprovider:
condition: service_started
flagd:
condition: service_started
logging: *logging

# Frontend Proxy (Envoy)
Expand Down Expand Up @@ -352,6 +356,8 @@ services:
- OTEL_COLLECTOR_PORT_HTTP
- OTEL_RESOURCE_ATTRIBUTES
- ENVOY_PORT
- FLAGD_HOST
- FLAGD_PORT
depends_on:
frontend:
condition: service_started
Expand Down
10 changes: 10 additions & 0 deletions src/flagd/demo.flagd.json
Original file line number Diff line number Diff line change
Expand Up @@ -96,6 +96,16 @@
"off": 0
},
"defaultVariant": "off"
},
"imageSlowLoad": {
"description": "slow loading images in the frontend",
"state": "ENABLED",
"variants": {
"10sec": 10000,
"5sec": 5000,
"off": 0
},
"defaultVariant": "off"
}
}
}
53 changes: 51 additions & 2 deletions src/frontend/components/ProductCard/ProductCard.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,11 +5,45 @@ import { CypressFields } from '../../utils/Cypress';
import { Product } from '../../protos/demo';
import ProductPrice from '../ProductPrice';
import * as S from './ProductCard.styled';
import { useState, useEffect } from 'react';
import { RequestInfo } from 'undici-types';
import { useNumberFlagValue, OpenFeature } from '@openfeature/react-sdk';
import { FlagdWebProvider } from '@openfeature/flagd-web-provider';

interface IProps {
product: Product;
}

async function getImageWithHeaders(url: RequestInfo, headers: Record<string,string>) {
const res = await fetch(url, { headers });
return await res.blob();
}

/**
* We connect to flagd through the envoy proxy, straight from the browser, for this we need to know the current hostname and port.
* During building and serverside rendering, these are undefined so we use some conditionals and default values.
*/
let hostname = "";
let port = 80;
let tls = false;

if (typeof window !== "undefined" && window.location) {
hostname = window.location.hostname;
port = window.location.port ? parseInt(window.location.port, 10) : 80;
tls = window.location.protocol === "https:";
}


OpenFeature.setProvider(new FlagdWebProvider({
host: hostname,
pathPrefix: "flagservice",
port: port,
tls: tls,
maxRetries: 3,
maxDelay: 10000,
}));


const ProductCard = ({
product: {
id,
Expand All @@ -20,12 +54,27 @@ const ProductCard = ({
units: 0,
nanos: 0,
},
},
}
}: IProps) => {

const imageSlowLoad = useNumberFlagValue('imageSlowLoad', 0);
const headers = {'x-envoy-fault-delay-request': imageSlowLoad.toString(),
'Cache-Control': 'no-cache'}

const [imageSrc, setImageSrc] =useState<string>("");

useEffect(() => {
getImageWithHeaders("/images/products/" + picture, headers).then((blob) => {
setImageSrc(URL.createObjectURL(blob));
});
}, [picture]);



return (
<S.Link href={`/product/${id}`}>
<S.ProductCard data-cy={CypressFields.ProductCard}>
<S.Image $src={"/images/products/" + picture} />
<S.Image $src={imageSrc} />
<div>
<S.ProductName>{name}</S.ProductName>
<S.ProductPrice>
Expand Down
Loading

0 comments on commit 4636590

Please sign in to comment.