Merge pull request #5526 from vegaprotocol/5409-funding-countdown
feat(trading): poll market info, and last fundingPeriod
This commit is contained in:
commit
9fbb7a13e6
@ -188,12 +188,11 @@ const useNow = () => {
|
|||||||
return now;
|
return now;
|
||||||
};
|
};
|
||||||
|
|
||||||
const useEvery = (marketId: string) => {
|
const useEvery = (marketId: string, skip: boolean) => {
|
||||||
const { data: marketTradingMode } = useMarketTradingMode(marketId);
|
|
||||||
const { data: marketInfo } = useDataProvider({
|
const { data: marketInfo } = useDataProvider({
|
||||||
dataProvider: marketInfoProvider,
|
dataProvider: marketInfoProvider,
|
||||||
variables: { marketId },
|
variables: { marketId },
|
||||||
skip: !marketTradingMode || isMarketInAuction(marketTradingMode),
|
skip,
|
||||||
});
|
});
|
||||||
let every: number | undefined = undefined;
|
let every: number | undefined = undefined;
|
||||||
const sourceType =
|
const sourceType =
|
||||||
@ -211,8 +210,10 @@ const useEvery = (marketId: string) => {
|
|||||||
return every;
|
return every;
|
||||||
};
|
};
|
||||||
|
|
||||||
const useStartTime = (marketId: string) => {
|
const useStartTime = (marketId: string, skip: boolean) => {
|
||||||
const { data: fundingPeriods } = useFundingPeriodsQuery({
|
const { data: fundingPeriods } = useFundingPeriodsQuery({
|
||||||
|
pollInterval: 5000,
|
||||||
|
skip,
|
||||||
variables: {
|
variables: {
|
||||||
marketId: marketId,
|
marketId: marketId,
|
||||||
pagination: { first: 1 },
|
pagination: { first: 1 },
|
||||||
@ -246,8 +247,10 @@ const useFormatCountdown = (
|
|||||||
|
|
||||||
export const FundingCountdown = ({ marketId }: { marketId: string }) => {
|
export const FundingCountdown = ({ marketId }: { marketId: string }) => {
|
||||||
const now = useNow();
|
const now = useNow();
|
||||||
const startTime = useStartTime(marketId);
|
const { data: marketTradingMode } = useMarketTradingMode(marketId);
|
||||||
const every = useEvery(marketId);
|
const skip = !marketTradingMode || isMarketInAuction(marketTradingMode);
|
||||||
|
const startTime = useStartTime(marketId, skip);
|
||||||
|
const every = useEvery(marketId, skip);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div data-testid="funding-countdown">
|
<div data-testid="funding-countdown">
|
||||||
|
4
apps/trading/e2e/poetry.lock
generated
4
apps/trading/e2e/poetry.lock
generated
@ -1,4 +1,4 @@
|
|||||||
# This file is automatically @generated by Poetry 1.6.1 and should not be changed by hand.
|
# This file is automatically @generated by Poetry 1.7.1 and should not be changed by hand.
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "certifi"
|
name = "certifi"
|
||||||
@ -1161,7 +1161,7 @@ profile = ["pytest-profiling", "snakeviz"]
|
|||||||
type = "git"
|
type = "git"
|
||||||
url = "https://github.com/vegaprotocol/vega-market-sim.git/"
|
url = "https://github.com/vegaprotocol/vega-market-sim.git/"
|
||||||
reference = "fix/genesis_panic"
|
reference = "fix/genesis_panic"
|
||||||
resolved_reference = "6cad0ac6adc30830be219047af0d725fed8a6998"
|
resolved_reference = "de30d2d4c7a1b81a830527ca76473e23ef59de12"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "websocket-client"
|
name = "websocket-client"
|
||||||
|
@ -280,7 +280,7 @@ def test_market_info_proposal(page: Page, vega: VegaService):
|
|||||||
"href", re.compile(r"(\/proposals\/propose\/update-market)")
|
"href", re.compile(r"(\/proposals\/propose\/update-market)")
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@pytest.mark.skip("tbd-market-sim")
|
||||||
def test_market_info_succession_line(page: Page, vega: VegaService):
|
def test_market_info_succession_line(page: Page, vega: VegaService):
|
||||||
page.get_by_test_id(market_title_test_id).get_by_text("Succession line").click()
|
page.get_by_test_id(market_title_test_id).get_by_text("Succession line").click()
|
||||||
market_id = vega.find_market_id("BTC:DAI_2023")
|
market_id = vega.find_market_id("BTC:DAI_2023")
|
||||||
|
@ -7,6 +7,7 @@ import type {
|
|||||||
FetchResult,
|
FetchResult,
|
||||||
ErrorPolicy,
|
ErrorPolicy,
|
||||||
ApolloQueryResult,
|
ApolloQueryResult,
|
||||||
|
QueryOptions,
|
||||||
} from '@apollo/client';
|
} from '@apollo/client';
|
||||||
import type { GraphQLErrors } from '@apollo/client/errors';
|
import type { GraphQLErrors } from '@apollo/client/errors';
|
||||||
import type { Subscription } from 'zen-observable-ts';
|
import type { Subscription } from 'zen-observable-ts';
|
||||||
@ -158,6 +159,7 @@ interface DataProviderParams<
|
|||||||
};
|
};
|
||||||
fetchPolicy?: FetchPolicy;
|
fetchPolicy?: FetchPolicy;
|
||||||
resetDelay?: number;
|
resetDelay?: number;
|
||||||
|
pollInterval?: number;
|
||||||
additionalContext?: Record<string, unknown>;
|
additionalContext?: Record<string, unknown>;
|
||||||
errorPolicyGuard?: (graphqlErrors: GraphQLErrors) => boolean;
|
errorPolicyGuard?: (graphqlErrors: GraphQLErrors) => boolean;
|
||||||
getQueryVariables?: (variables: Variables) => QueryVariables;
|
getQueryVariables?: (variables: Variables) => QueryVariables;
|
||||||
@ -198,6 +200,7 @@ function makeDataProviderInternal<
|
|||||||
errorPolicyGuard,
|
errorPolicyGuard,
|
||||||
getQueryVariables,
|
getQueryVariables,
|
||||||
getSubscriptionVariables,
|
getSubscriptionVariables,
|
||||||
|
pollInterval,
|
||||||
}: DataProviderParams<
|
}: DataProviderParams<
|
||||||
QueryData,
|
QueryData,
|
||||||
Data,
|
Data,
|
||||||
@ -222,6 +225,7 @@ function makeDataProviderInternal<
|
|||||||
let client: ApolloClient<object>;
|
let client: ApolloClient<object>;
|
||||||
let subscription: Subscription[] | undefined;
|
let subscription: Subscription[] | undefined;
|
||||||
let pageInfo: PageInfo | null = null;
|
let pageInfo: PageInfo | null = null;
|
||||||
|
let watchQuerySubscription: Subscription | null = null;
|
||||||
|
|
||||||
// notify single callback about current state, delta is passes optionally only if notify was invoked onNext
|
// notify single callback about current state, delta is passes optionally only if notify was invoked onNext
|
||||||
const notify = (
|
const notify = (
|
||||||
@ -243,34 +247,100 @@ function makeDataProviderInternal<
|
|||||||
callbacks.forEach((callback) => notify(callback, updateData));
|
callbacks.forEach((callback) => notify(callback, updateData));
|
||||||
};
|
};
|
||||||
|
|
||||||
const call = (
|
const getQueryOptions = (
|
||||||
|
pagination?: Pagination,
|
||||||
|
policy?: ErrorPolicy
|
||||||
|
): QueryOptions<OperationVariables, QueryData> => ({
|
||||||
|
query,
|
||||||
|
variables: {
|
||||||
|
...(getQueryVariables ? getQueryVariables(variables) : variables),
|
||||||
|
...(pagination && {
|
||||||
|
// let the variables pagination be prior to provider param
|
||||||
|
pagination: {
|
||||||
|
...pagination,
|
||||||
|
...(variables?.['pagination'] ?? null),
|
||||||
|
},
|
||||||
|
}),
|
||||||
|
},
|
||||||
|
fetchPolicy: fetchPolicy || 'no-cache',
|
||||||
|
context: additionalContext,
|
||||||
|
errorPolicy: policy || 'none',
|
||||||
|
pollInterval,
|
||||||
|
});
|
||||||
|
|
||||||
|
const onNext = (res: ApolloQueryResult<QueryData>) => {
|
||||||
|
data = getData(res.data, variables);
|
||||||
|
if (data && pagination) {
|
||||||
|
if (!(data instanceof Array)) {
|
||||||
|
throw new Error(
|
||||||
|
'data needs to be instance of Edge[] when using pagination'
|
||||||
|
);
|
||||||
|
}
|
||||||
|
pageInfo = pagination.getPageInfo(res.data);
|
||||||
|
}
|
||||||
|
// if there was some updates received from subscription during initial query loading apply them on just received data
|
||||||
|
if (update && data && updateQueue && updateQueue.length > 0) {
|
||||||
|
while (updateQueue.length) {
|
||||||
|
const delta = updateQueue.shift();
|
||||||
|
if (delta) {
|
||||||
|
setData(update(data, delta, reload, variables));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
loaded = true;
|
||||||
|
};
|
||||||
|
|
||||||
|
const onError = (e: Error) => {
|
||||||
|
if (isNotFoundGraphQLError(e, ['party'])) {
|
||||||
|
data = getData(null, variables);
|
||||||
|
loaded = true;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
// if error will occur data provider stops subscription
|
||||||
|
error = e;
|
||||||
|
subscriptionUnsubscribe();
|
||||||
|
};
|
||||||
|
|
||||||
|
const onComplete = (isUpdate?: boolean) => {
|
||||||
|
loading = false;
|
||||||
|
notifyAll({ isUpdate });
|
||||||
|
};
|
||||||
|
|
||||||
|
const callWatchQuery = (pagination?: Pagination, policy?: ErrorPolicy) => {
|
||||||
|
let onNextCalled = false;
|
||||||
|
try {
|
||||||
|
watchQuerySubscription = client
|
||||||
|
.watchQuery(getQueryOptions(pagination, policy))
|
||||||
|
.subscribe(
|
||||||
|
(res) => {
|
||||||
|
onNext(res);
|
||||||
|
onComplete(onNextCalled);
|
||||||
|
onNextCalled = true;
|
||||||
|
},
|
||||||
|
(error) => {
|
||||||
|
onError(error as Error);
|
||||||
|
onComplete();
|
||||||
|
}
|
||||||
|
);
|
||||||
|
} catch (e) {
|
||||||
|
onError(e as Error);
|
||||||
|
onComplete();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
const callQuery = (
|
||||||
pagination?: Pagination,
|
pagination?: Pagination,
|
||||||
policy?: ErrorPolicy
|
policy?: ErrorPolicy
|
||||||
): Promise<ApolloQueryResult<QueryData>> =>
|
): Promise<ApolloQueryResult<QueryData>> =>
|
||||||
client
|
client
|
||||||
.query<QueryData>({
|
.query<QueryData>(getQueryOptions(pagination, policy))
|
||||||
query,
|
|
||||||
variables: {
|
|
||||||
...(getQueryVariables ? getQueryVariables(variables) : variables),
|
|
||||||
...(pagination && {
|
|
||||||
// let the variables pagination be prior to provider param
|
|
||||||
pagination: {
|
|
||||||
...pagination,
|
|
||||||
...(variables?.['pagination'] ?? null),
|
|
||||||
},
|
|
||||||
}),
|
|
||||||
},
|
|
||||||
fetchPolicy: fetchPolicy || 'no-cache',
|
|
||||||
context: additionalContext,
|
|
||||||
errorPolicy: policy || 'none',
|
|
||||||
})
|
|
||||||
.catch((err) => {
|
.catch((err) => {
|
||||||
if (
|
if (
|
||||||
err.graphQLErrors &&
|
err.graphQLErrors &&
|
||||||
errorPolicyGuard &&
|
errorPolicyGuard &&
|
||||||
errorPolicyGuard(err.graphQLErrors)
|
errorPolicyGuard(err.graphQLErrors)
|
||||||
) {
|
) {
|
||||||
return call(pagination, 'ignore');
|
return callQuery(pagination, 'ignore');
|
||||||
} else {
|
} else {
|
||||||
throw err;
|
throw err;
|
||||||
}
|
}
|
||||||
@ -294,7 +364,7 @@ function makeDataProviderInternal<
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const res = await call(paginationVariables);
|
const res = await callQuery(paginationVariables);
|
||||||
|
|
||||||
const insertionData = getData(res.data, variables);
|
const insertionData = getData(res.data, variables);
|
||||||
const insertionPageInfo = pagination.getPageInfo(res.data);
|
const insertionPageInfo = pagination.getPageInfo(res.data);
|
||||||
@ -329,7 +399,7 @@ function makeDataProviderInternal<
|
|||||||
variables,
|
variables,
|
||||||
fetchPolicy,
|
fetchPolicy,
|
||||||
})
|
})
|
||||||
.subscribe(onNext, onError)
|
.subscribe(subscriptionOnNext, subscriptionOnError)
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -347,39 +417,16 @@ function makeDataProviderInternal<
|
|||||||
const paginationVariables = pagination
|
const paginationVariables = pagination
|
||||||
? { first: pagination.first }
|
? { first: pagination.first }
|
||||||
: undefined;
|
: undefined;
|
||||||
|
if (pollInterval) {
|
||||||
|
callWatchQuery();
|
||||||
|
return;
|
||||||
|
}
|
||||||
try {
|
try {
|
||||||
const res = await call(paginationVariables);
|
onNext(await callQuery(paginationVariables));
|
||||||
data = getData(res.data, variables);
|
|
||||||
if (data && pagination) {
|
|
||||||
if (!(data instanceof Array)) {
|
|
||||||
throw new Error(
|
|
||||||
'data needs to be instance of Edge[] when using pagination'
|
|
||||||
);
|
|
||||||
}
|
|
||||||
pageInfo = pagination.getPageInfo(res.data);
|
|
||||||
}
|
|
||||||
// if there was some updates received from subscription during initial query loading apply them on just received data
|
|
||||||
if (update && data && updateQueue && updateQueue.length > 0) {
|
|
||||||
while (updateQueue.length) {
|
|
||||||
const delta = updateQueue.shift();
|
|
||||||
if (delta) {
|
|
||||||
setData(update(data, delta, reload, variables));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
loaded = true;
|
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
if (isNotFoundGraphQLError(e as Error, ['party'])) {
|
onError(e as Error);
|
||||||
data = getData(null, variables);
|
|
||||||
loaded = true;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
// if error will occur data provider stops subscription
|
|
||||||
error = e as Error;
|
|
||||||
subscriptionUnsubscribe();
|
|
||||||
} finally {
|
} finally {
|
||||||
loading = false;
|
onComplete(isUpdate);
|
||||||
notifyAll({ isUpdate });
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -399,7 +446,7 @@ function makeDataProviderInternal<
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
const onNext = ({
|
const subscriptionOnNext = ({
|
||||||
data: subscriptionData,
|
data: subscriptionData,
|
||||||
}: FetchResult<SubscriptionData>) => {
|
}: FetchResult<SubscriptionData>) => {
|
||||||
if (!subscriptionData || !getDelta || !update) {
|
if (!subscriptionData || !getDelta || !update) {
|
||||||
@ -418,7 +465,7 @@ function makeDataProviderInternal<
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
const onError = (e: Error) => {
|
const subscriptionOnError = (e: Error) => {
|
||||||
error = e;
|
error = e;
|
||||||
subscriptionUnsubscribe();
|
subscriptionUnsubscribe();
|
||||||
notifyAll();
|
notifyAll();
|
||||||
@ -442,6 +489,9 @@ function makeDataProviderInternal<
|
|||||||
};
|
};
|
||||||
|
|
||||||
const reset = () => {
|
const reset = () => {
|
||||||
|
if (watchQuerySubscription) {
|
||||||
|
watchQuerySubscription.unsubscribe();
|
||||||
|
}
|
||||||
subscriptionUnsubscribe();
|
subscriptionUnsubscribe();
|
||||||
initialized = false;
|
initialized = false;
|
||||||
data = null;
|
data = null;
|
||||||
|
@ -34,6 +34,7 @@ export const marketInfoProvider = makeDataProvider<
|
|||||||
query: MarketInfoDocument,
|
query: MarketInfoDocument,
|
||||||
getData,
|
getData,
|
||||||
errorPolicyGuard: marketDataErrorPolicyGuard,
|
errorPolicyGuard: marketDataErrorPolicyGuard,
|
||||||
|
pollInterval: 5000,
|
||||||
});
|
});
|
||||||
|
|
||||||
export const marketInfoWithDataProvider = makeDerivedDataProvider<
|
export const marketInfoWithDataProvider = makeDerivedDataProvider<
|
||||||
|
Loading…
Reference in New Issue
Block a user