From 0b8ad76b0f1fb2adef8a7db3f8fd7bd84c3389b4 Mon Sep 17 00:00:00 2001 From: mantikoros Date: Wed, 5 Jan 2022 12:23:58 -0600 Subject: [PATCH] global warming: warm up all cloud functions on client --- functions/src/create-contract.ts | 3 +++ web/components/bet-panel.tsx | 11 +++++++---- web/components/bets-list.tsx | 12 ++++++++---- web/components/resolution-panel.tsx | 12 +++++++----- web/lib/firebase/api-call.ts | 7 +++++++ web/pages/create.tsx | 12 +++++++----- web/pages/make-predictions.tsx | 6 ++---- 7 files changed, 41 insertions(+), 22 deletions(-) diff --git a/functions/src/create-contract.ts b/functions/src/create-contract.ts index 0b0796f6..d37919ab 100644 --- a/functions/src/create-contract.ts +++ b/functions/src/create-contract.ts @@ -29,6 +29,9 @@ export const createContract = functions const { question, description, initialProb, ante, closeTime } = data + if (!question || !initialProb) + return { status: 'error', message: 'Missing contract attributes' } + if (ante !== undefined && (ante < 0 || ante > creator.balance)) return { status: 'error', message: 'Invalid ante' } diff --git a/web/components/bet-panel.tsx b/web/components/bet-panel.tsx index 4bb5702d..f6f35676 100644 --- a/web/components/bet-panel.tsx +++ b/web/components/bet-panel.tsx @@ -1,6 +1,6 @@ import { getFunctions, httpsCallable } from 'firebase/functions' import clsx from 'clsx' -import React, { useState } from 'react' +import React, { useEffect, useState } from 'react' import { useUser } from '../hooks/use-user' import { Contract } from '../lib/firebase/contracts' @@ -24,8 +24,14 @@ import { firebaseLogin } from '../lib/firebase/users' import { OutcomeLabel } from './outcome-label' import { AdvancedPanel } from './advanced-panel' import { Bet } from '../lib/firebase/bets' +import { placeBet } from '../lib/firebase/api-call' export function BetPanel(props: { contract: Contract; className?: string }) { + useEffect(() => { + // warm up cloud function + placeBet({}).catch() + }, []) + const { contract, className } = props const user = useUser() @@ -212,6 +218,3 @@ export function BetPanel(props: { contract: Contract; className?: string }) { ) } - -const functions = getFunctions() -export const placeBet = httpsCallable(functions, 'placeBet') diff --git a/web/components/bets-list.tsx b/web/components/bets-list.tsx index 3cbf4ace..b622c58e 100644 --- a/web/components/bets-list.tsx +++ b/web/components/bets-list.tsx @@ -2,6 +2,8 @@ import Link from 'next/link' import _ from 'lodash' import dayjs from 'dayjs' import { useEffect, useState } from 'react' +import clsx from 'clsx' + import { useUserBets } from '../hooks/use-user-bets' import { Bet } from '../lib/firebase/bets' import { User } from '../lib/firebase/users' @@ -20,8 +22,7 @@ import { calculateSaleAmount, resolvedPayout, } from '../lib/calculate' -import clsx from 'clsx' -import { cloudFunction } from '../lib/firebase/api-call' +import { sellBet } from '../lib/firebase/api-call' import { ConfirmationButton } from './confirmation-button' import { OutcomeLabel, YesLabel, NoLabel, MarketLabel } from './outcome-label' @@ -341,9 +342,12 @@ function BetRow(props: { bet: Bet; contract: Contract; sale?: Bet }) { ) } -const sellBet = cloudFunction('sellBet') - function SellButton(props: { contract: Contract; bet: Bet }) { + useEffect(() => { + // warm up cloud function + sellBet({}).catch() + }, []) + const { contract, bet } = props const [isSubmitting, setIsSubmitting] = useState(false) diff --git a/web/components/resolution-panel.tsx b/web/components/resolution-panel.tsx index d5ccbfd5..3e282fa8 100644 --- a/web/components/resolution-panel.tsx +++ b/web/components/resolution-panel.tsx @@ -1,6 +1,5 @@ import clsx from 'clsx' -import React, { useState } from 'react' -import { getFunctions, httpsCallable } from 'firebase/functions' +import React, { useEffect, useState } from 'react' import { Contract } from '../lib/firebase/contracts' import { Col } from './layout/col' @@ -9,15 +8,18 @@ import { User } from '../lib/firebase/users' import { YesNoCancelSelector } from './yes-no-selector' import { Spacer } from './layout/spacer' import { ConfirmationButton as ConfirmationButton } from './confirmation-button' - -const functions = getFunctions() -export const resolveMarket = httpsCallable(functions, 'resolveMarket') +import { resolveMarket } from '../lib/firebase/api-call' export function ResolutionPanel(props: { creator: User contract: Contract className?: string }) { + useEffect(() => { + // warm up cloud function + resolveMarket({}).catch() + }, []) + const { contract, className } = props const [outcome, setOutcome] = useState< diff --git a/web/lib/firebase/api-call.ts b/web/lib/firebase/api-call.ts index fc054386..3d541291 100644 --- a/web/lib/firebase/api-call.ts +++ b/web/lib/firebase/api-call.ts @@ -4,3 +4,10 @@ const functions = getFunctions() export const cloudFunction = (name: string) => httpsCallable(functions, name) +export const createContract = cloudFunction('createContract') + +export const placeBet = cloudFunction('placeBet') + +export const resolveMarket = cloudFunction('resolveMarket') + +export const sellBet = cloudFunction('sellBet') diff --git a/web/pages/create.tsx b/web/pages/create.tsx index 2d6c2027..ab76e667 100644 --- a/web/pages/create.tsx +++ b/web/pages/create.tsx @@ -2,7 +2,6 @@ import router from 'next/router' import { useEffect, useState } from 'react' import clsx from 'clsx' import dayjs from 'dayjs' -import { getFunctions, httpsCallable } from 'firebase/functions' import { CreatorContractsList } from '../components/contracts-list' import { Spacer } from '../components/layout/spacer' @@ -12,6 +11,7 @@ import { Contract, path } from '../lib/firebase/contracts' import { Page } from '../components/page' import { formatMoney } from '../lib/util/format' import { AdvancedPanel } from '../components/advanced-panel' +import { createContract } from '../lib/firebase/api-call' // Allow user to create a new contract export default function NewContract() { @@ -19,7 +19,12 @@ export default function NewContract() { useEffect(() => { if (creator === null) router.push('/') - }) + }, [creator]) + + useEffect(() => { + // warm up function + createContract({}).catch() + }, []) const [initialProb, setInitialProb] = useState(50) const [question, setQuestion] = useState('') @@ -225,9 +230,6 @@ export default function NewContract() { ) } -const functions = getFunctions() -export const createContract = httpsCallable(functions, 'createContract') - // Given a date string like '2022-04-02', // return the time just before midnight on that date (in the user's local time), as millis since epoch function dateToMillis(date: string) { diff --git a/web/pages/make-predictions.tsx b/web/pages/make-predictions.tsx index 23144ff0..c2a2fe5f 100644 --- a/web/pages/make-predictions.tsx +++ b/web/pages/make-predictions.tsx @@ -1,7 +1,7 @@ import clsx from 'clsx' -import { getFunctions, httpsCallable } from 'firebase/functions' import Link from 'next/link' import { useState } from 'react' + import { Col } from '../components/layout/col' import { Row } from '../components/layout/row' import { Spacer } from '../components/layout/spacer' @@ -9,11 +9,9 @@ import { Linkify } from '../components/linkify' import { Page } from '../components/page' import { Title } from '../components/title' import { useUser } from '../hooks/use-user' +import { createContract } from '../lib/firebase/api-call' import { compute, Contract, path } from '../lib/firebase/contracts' -const functions = getFunctions() -export const createContract = httpsCallable(functions, 'createContract') - type Prediction = { question: string description: string