Skip to content

Commit

Permalink
fix: schema fetching for custom endpoints
Browse files Browse the repository at this point in the history
  • Loading branch information
timsuchanek committed May 23, 2018
1 parent 543042c commit d8a17e8
Show file tree
Hide file tree
Showing 2 changed files with 60 additions and 50 deletions.
106 changes: 58 additions & 48 deletions packages/graphql-playground-react/src/components/Playground.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@ import {
getFile,
getHeaders,
getIsReloadingSchema,
getEndpoint,
} from '../state/sessions/selectors'
import { getHistoryOpen } from '../state/general/selectors'
import {
Expand All @@ -48,6 +49,7 @@ import { Session } from '../state/sessions/reducers'
import { getWorkspaceId } from './Playground/util/getWorkspaceId'
import { getSettings, getSettingsString } from '../state/workspace/reducers'
import { Backoff } from './Playground/util/fibonacci-backoff'
import { debounce } from 'lodash'

export interface Response {
resultID: string
Expand All @@ -57,6 +59,7 @@ export interface Response {

export interface Props {
endpoint: string
sessionEndpoint: string
subscriptionEndpoint?: string
projectId?: string
shareEnabled?: boolean
Expand Down Expand Up @@ -130,10 +133,34 @@ export class Playground extends React.PureComponent<Props & ReduxProps, State> {
apolloLinks: { [sessionId: string]: any } = {}
observers: { [sessionId: string]: any } = {}
graphiqlComponents: any[] = []

// debounce as we call this on each http header or endpoint edit
getSchema = debounce(
async (props: Props & ReduxProps = this.props) => {
if (this.mounted && this.state.schema) {
this.setState({ schema: undefined })
}
let first = true
if (this.backoff) {
this.backoff.stop()
}
this.backoff = new Backoff(async () => {
if (first) {
await this.schemaGetter(props)
first = false
} else {
await this.schemaGetter()
}
})
this.backoff.start()
},
300,
{ trailing: true }, // important to not miss the last call
) as any

private backoff: Backoff
private initialIndex: number = -1
private mounted = false
private fetchingSchema = false

constructor(props: Props & ReduxProps) {
super(props)
Expand Down Expand Up @@ -168,15 +195,16 @@ export class Playground extends React.PureComponent<Props & ReduxProps, State> {
this.mounted = true
}

componentWillReceiveProps(nextProps) {
componentWillReceiveProps(nextProps: Props & ReduxProps) {
if (this.props.createApolloLink !== nextProps.createApolloLink) {
setLinkCreator(nextProps.createApolloLink)
}
if (
nextProps.headers !== this.props.headers ||
nextProps.endpoint !== this.props.endpoint ||
nextProps.workspaceName !== this.props.workspaceName ||
nextProps.sessionHeaders !== this.props.sessionHeaders
nextProps.sessionHeaders !== this.props.sessionHeaders ||
nextProps.sessionEndpoint !== this.props.sessionEndpoint
) {
this.getSchema(nextProps)
}
Expand All @@ -203,54 +231,35 @@ export class Playground extends React.PureComponent<Props & ReduxProps, State> {
}
}

async getSchema(props = this.props) {
if (this.mounted && this.state.schema) {
this.setState({ schema: undefined })
}
let first = true
if (this.backoff) {
this.backoff.stop()
}
this.backoff = new Backoff(async () => {
if (first) {
await this.schemaGetter(props)
first = false
} else {
await this.schemaGetter()
async schemaGetter(propsInput?: Props & ReduxProps) {
const props = this.props || propsInput
const endpoint = props.sessionEndpoint || props.endpoint
try {
const data = {
endpoint,
headers:
props.sessionHeaders && props.sessionHeaders.length > 0
? props.sessionHeaders
: JSON.stringify(props.headers),
}
})
this.backoff.start()
}

async schemaGetter(props = this.props) {
if (!this.fetchingSchema) {
try {
const data = {
endpoint: props.endpoint,
headers:
props.sessionHeaders && props.sessionHeaders.length > 0
? props.sessionHeaders
: JSON.stringify(props.headers),
}
const schema = await schemaFetcher.fetch(data)
schemaFetcher.subscribe(data, newSchema => {
if (data.endpoint === this.props.endpoint) {
this.setState({ schema: newSchema })
}
})
if (schema) {
this.setState({ schema: schema.schema })
this.props.schemaFetchingSuccess(
props.endpoint,
schema.tracingSupported,
)
this.backoff.stop()
const schema = await schemaFetcher.fetch(data)
schemaFetcher.subscribe(data, newSchema => {
if (
data.endpoint === this.props.endpoint ||
data.endpoint === this.props.sessionEndpoint
) {
this.setState({ schema: newSchema })
}
} catch (e) {
// tslint:disable-next-line
console.error(e)
this.props.schemaFetchingError(props.endpoint, e.message)
})
if (schema) {
this.setState({ schema: schema.schema })
this.props.schemaFetchingSuccess(data.endpoint, schema.tracingSupported)
this.backoff.stop()
}
} catch (e) {
// tslint:disable-next-line
console.error(e)
this.props.schemaFetchingError(endpoint, e.message)
}
}

Expand Down Expand Up @@ -350,6 +359,7 @@ const mapStateToProps = createStructuredSelector({
settings: getSettings,
settingsString: getSettingsString,
isReloadingSchema: getIsReloadingSchema,
sessionEndpoint: getEndpoint,
})

export default connect(mapStateToProps, {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,11 +20,11 @@ export class Backoff {
const fn = async () => {
await this.cb()
this.count++
// The first 15 attempts are fast, then fibonacci starts with n = 3
// The first 5 attempts are fast, then fibonacci starts with n = 3
if (this.running && this.count < this.maxRetries) {
this.timeout = setTimeout(
fn,
(this.count < 3 ? 5 : fibonacci(this.count - 12)) * 1000,
(this.count < 3 ? 5 : fibonacci(this.count - 5)) * 1000,
)
}
}
Expand Down

0 comments on commit d8a17e8

Please sign in to comment.