Skip to content

Commit

Permalink
memory management
Browse files Browse the repository at this point in the history
Merge pull request #67 from cdriesler/memory-management
  • Loading branch information
cdriesler authored May 12, 2021
2 parents 548d87d + b7b8675 commit 9b595f6
Show file tree
Hide file tree
Showing 12 changed files with 144 additions and 224 deletions.
1 change: 1 addition & 0 deletions api/src/gql/resolvers/Query/getSolutionStatus.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ type SolutionStatus = {
started_at?: string
finished_at?: string
duration?: string
parameter_count?: string
}

export const getSolutionStatus = (
Expand Down
4 changes: 3 additions & 1 deletion api/src/gql/resolvers/Query/getSolutionValue.ts
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,9 @@ export const getSolutionValue = async (
data: reply,
}

resolve(response)
db.del(key, (err, reply) => {
resolve(response)
})
})
})
}
1 change: 1 addition & 0 deletions api/src/gql/schema.ts
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,7 @@ export const schema = gql`
started_at: String
finished_at: String
duration: Int
parameter_count: String
}
type SolutionValue {
Expand Down
61 changes: 30 additions & 31 deletions app/components/queue/lib/components/QueueJobEntry.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -10,15 +10,14 @@ type QueueJobEntryProps = {
}

export const QueueJobEntry = ({ sessionId, solutionId, registerGraph }: QueueJobEntryProps): React.ReactElement => {
const client = useApolloClient()
const { data, stopPolling } = useQuery(SOLUTION_STATUS, { variables: { sessionId, solutionId }, pollInterval: 500 })

const status = data?.getSolutionStatus?.status?.toLowerCase() ?? 'waiting'
const end = data?.getSolutionStatus?.finished_at ?? data?.getSolutionStatus?.started_at
const userColor = stringToColour(sessionId)
const parameterCount = data?.getSolutionStatus?.parameter_count ?? '-'

const [duration, setDuration] = useState<string>()
const [graph, setGraph] = useState<Glasshopper.Element.Base[]>()
// const [graph, setGraph] = useState<Glasshopper.Element.Base[]>()

const getStatusColor = (status: string): string => {
switch (status) {
Expand Down Expand Up @@ -54,12 +53,12 @@ export const QueueJobEntry = ({ sessionId, solutionId, registerGraph }: QueueJob
stopPolling()
setDuration(data.getSolutionStatus.duration)

client.query({ query: GRAPH_JSON, variables: { sessionId, solutionId } }).then(({ data }) => {
const json = data.getGraphJson
// client.query({ query: GRAPH_JSON, variables: { sessionId, solutionId } }).then(({ data }) => {
// const json = data.getGraphJson

const graph: Glasshopper.Element.Base[] = Object.values(JSON.parse(json))
setGraph(graph)
})
// const graph: Glasshopper.Element.Base[] = Object.values(JSON.parse(json))
// setGraph(graph)
// })
}
}, [status])

Expand All @@ -81,35 +80,35 @@ export const QueueJobEntry = ({ sessionId, solutionId, registerGraph }: QueueJob
style={{ transform: 'translateY(4px)' }}
>
<div className="leading-4 flex flex-row justify-end font-panel text-xl font-bold">
{duration}/{graph?.length ?? ''}
{duration}/{parameterCount}
</div>
<div className="flex flex-row justify-end font-panel text-md">{getDateString(end)}</div>
</div>
</div>
)

return (
<div className={`${status === 'failed' ? 'bg-red-200' : ''} w-full h-10 p-2 mb-2 rounded-md flex items-center`}>
<div className="w-6 h-6 mr-2 rounded-full" style={{ background: statusColor }} />
<div className="w-6 h-6 mr-2 rounded-full" style={{ background: userColor }} />
{status === 'failed' ? (
<div className="flex-grow flex flex-col items-end">
<p className="text-xs">{sessionId}</p>
<p className="text-xs">{solutionId}</p>
</div>
) : (
<>
<p>{sessionId.split('-')[1]}</p>
<p> : </p>
<p>{solutionId.split('-')[1]}</p>
<div className="flex-grow flex justify-end items-center">
{graph ? <p>({graph.length})</p> : null}
{duration ? <p className="ml-2">{duration}ms</p> : null}
</div>
</>
)}
</div>
)
// return (
// <div className={`${status === 'failed' ? 'bg-red-200' : ''} w-full h-10 p-2 mb-2 rounded-md flex items-center`}>
// <div className="w-6 h-6 mr-2 rounded-full" style={{ background: statusColor }} />
// <div className="w-6 h-6 mr-2 rounded-full" style={{ background: userColor }} />
// {status === 'failed' ? (
// <div className="flex-grow flex flex-col items-end">
// <p className="text-xs">{sessionId}</p>
// <p className="text-xs">{solutionId}</p>
// </div>
// ) : (
// <>
// <p>{sessionId.split('-')[1]}</p>
// <p> : </p>
// <p>{solutionId.split('-')[1]}</p>
// <div className="flex-grow flex justify-end items-center">
// {graph ? <p>({graph.length})</p> : null}
// {duration ? <p className="ml-2">{duration}ms</p> : null}
// </div>
// </>
// )}
// </div>
// )
}

const stringToColour = (str: string): string => {
Expand Down
6 changes: 5 additions & 1 deletion app/context/graph/hooks/useSolutionQuery.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,13 +17,17 @@ export const useSolutionQuery = (session: string, target: string, store: GraphSt

const client = useApolloClient()

const { data: solutionStatus, startPolling, stopPolling } = useQuery(SOLUTION_STATUS, {
const { data: solutionStatus, startPolling, stopPolling, error } = useQuery(SOLUTION_STATUS, {
variables: {
sessionId: session,
solutionId: waitingFor,
},
})

if (error) {
console.log(error)
}

useEffect(() => {
if (target === waitingFor) {
console.log('🐍 Skipping useSolutionQuery because incoming target matches current.')
Expand Down
5 changes: 5 additions & 0 deletions app/pages/alpha/graph.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import React from 'react'
import { NextPage, GetStaticProps } from 'next'
import Head from 'next/head'
import { Grasshopper } from 'glib'
import { Layout, Graph } from '@/components'
import { GraphManager } from '~/context/graph'
Expand All @@ -13,6 +14,10 @@ type GraphPageProps = {
const AlphaGraphPage: NextPage<GraphPageProps> = ({ config }) => {
return (
<Layout.Root>
<Head>
<title>nodepen: graph editor</title>
<meta name="description" content="The graph editor for NodePen. Create a grasshopper script on the web." />
</Head>
<GraphManager config={config}>
<Graph.Container />
</GraphManager>
Expand Down
5 changes: 5 additions & 0 deletions app/pages/alpha/scene.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import React from 'react'
import { NextPage, GetStaticProps } from 'next'
import Head from 'next/head'
import { Grasshopper } from 'glib'
import { Layout, Scene } from '@/components'
import { GraphManager } from '~/context/graph'
Expand All @@ -13,6 +14,10 @@ type ScenePageProps = {
const AlphaScenePage: NextPage<ScenePageProps> = ({ config }) => {
return (
<Layout.Root>
<Head>
<title>nodepen: scene viewer</title>
<meta name="description" content="The scene viewer for NodePen. View the 3D results of the current graph." />
</Head>
<GraphManager config={config}>
<Scene.Container />
</GraphManager>
Expand Down
126 changes: 76 additions & 50 deletions app/pages/index.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,15 @@
import React, { useState, useEffect, useMemo, useRef } from 'react'
import { GetServerSideProps, NextPage } from 'next'
import Head from 'next/head'
import { ApolloClient, InMemoryCache } from '@apollo/client'
import { QUEUE_STATUS } from '@/queries'

const Teaser = () => {
type HomeProps = {
solutionCount: number
userCount: number
}

const Home: NextPage<HomeProps> = ({ solutionCount, userCount }) => {
const [[w, h], setCircleDimensions] = useState<[number, number]>([0, 0])
const [offset, setOffset] = useState(0)

Expand Down Expand Up @@ -52,29 +61,50 @@ const Teaser = () => {
setCircleDimensions([clientWidth, clientHeight])
}, [])

// useEffect(() => {
// const speed = 0.25 / 45
// const march = setInterval(() => {
// setOffset((offset + speed) % 0.25)
// }, 40)
// return () => clearInterval(march)
// }, [offset])
useEffect(() => {
const speed = 0.25 / 45
const march = setInterval(() => {
setOffset((offset + speed) % 0.25)
}, 40)
return () => clearInterval(march)
}, [offset])

return (
<div className="w-vw h-vh bg-green flex flex-col justify-evenly items-center lg:flex-row">
<div className="w-48 h-48 md:w-76 md:h-76 relative">
<div className="absolute left-0 top-0 w-48 h-48 md:w-76 md:h-76 rounded-full bg-pale animate-swell z-10" />
<div className="absolute left-0 top-0 w-48 h-48 md:w-76 md:h-76 z-20">
<div className="flex flex-col items-center justify-center w-full h-full">
<a href="/alpha/graph" className="font-sans font-semibold text-sm">
<div className="w-48 h-10 card-mono rounded-md transition-all duration-150 ease-in-out hover:cursor-pointer transform translate-y-0 hover:translate-y-hov-sm flex flex-row">
<div className="flex-grow flex flex-row justify-center items-center">
<div className="font-sans font-semibold text-sm">LAUNCH NODEPEN</div>
</div>
</div>
</a>
</div>
</div>
<Head>
<title>nodepen: grasshopper online</title>
<meta
name="description"
content="NodePen is a web client for Grasshopper, the visual programming language for Rhino 3D. Same Grasshopper, new digs. Powered by Rhino
Compute."
/>
<meta name="keywords" content="grasshopper, online grasshopper, web grasshopper, rhino.compute" />
</Head>
<div className="w-76 flex flex-col items-center">
{solutionCount ? (
<>
<h2 className="flex flex-row text-darkgreen text-4xl font-semibold font-panel leading-5">
{`${solutionCount.toString()}`.split('').map((x, i) => (
<p className="animate-pulse" key={`sc-${i}`} style={{ animationDelay: `${(i / x.length) * 100}ms` }}>
{x}
</p>
))}
</h2>
<h3 className="text-swampgreen text-xl font-black font-panel mb-3">GRAPHS SOLVED</h3>
</>
) : null}
{userCount ? (
<>
<h2 className="flex flex-row text-darkgreen text-4xl font-semibold font-panel leading-5">
{`${userCount.toString()}`.split('').map((x, i) => (
<p className="animate-pulse" key={`uc-${i}`} style={{ animationDelay: `${(i / x.length) * 100}ms` }}>
{x}
</p>
))}
</h2>
<h3 className="text-swampgreen text-xl font-black font-panel mb-3">USERS</h3>
</>
) : null}
</div>
<div
ref={circleRef}
Expand All @@ -92,40 +122,17 @@ const Teaser = () => {
</div>
<div className="card-mono rounded-md w-64 lg:w-76 z-10 p-2 flex flex-col justify-center items-center">
<h1 className="font-display text-3xl mb-2">nodepen</h1>
<p className="font-sans font-semibold text-sm mb-2">PUBLIC TEST MAY 7-9</p>
<p className="font-sans font-semibold text-sm mb-2">SAME GRASSHOPPER, NEW DIGS</p>
</div>
</div>
<div className="flex flex-col">
<a
href="https://github.com/cdriesler/nodepen"
target="_blank"
rel="noreferrer"
className="font-sans font-semibold text-sm mb-2"
>
<div className="w-48 h-10 card-mono rounded-md transition-all duration-150 ease-in-out hover:cursor-pointer transform translate-y-0 hover:translate-y-hov-sm flex flex-row">
<div className="w-10 border-r-2 border-dark flex justify-center items-center">
<img alt="The official GitHub logo." src="/github.svg" width="24px" height="24px" />
</div>
<div className="flex-grow flex flex-row justify-center items-center">
<div className="font-sans font-semibold text-sm">VIEW SOURCE</div>
</div>
</div>
</a>
<a
href="https://twitter.com/cdriesler"
target="_blank"
rel="noreferrer"
className="font-sans font-semibold text-sm"
>
<div className="w-76 flex flex-col items-center">
<a href="/alpha/graph" className="font-sans font-semibold text-sm">
<div className="w-48 h-10 card-mono rounded-md transition-all duration-150 ease-in-out hover:cursor-pointer transform translate-y-0 hover:translate-y-hov-sm flex flex-row">
<div className="w-10 border-r-2 border-dark flex justify-center items-center">
<img alt="The official GitHub logo." src="/twitter.svg" width="24px" height="24px" />
</div>
<div className="flex-grow flex flex-row justify-center items-center">
<div className="font-sans font-semibold text-sm">VIEW UPDATES</div>
<div className="font-sans font-semibold text-sm">LAUNCH NODEPEN</div>
</div>
</div>
</a>
</a>{' '}
</div>

<style jsx>{`
Expand All @@ -150,4 +157,23 @@ const Teaser = () => {
)
}

export default Teaser
export const getServerSideProps: GetServerSideProps<HomeProps> = async () => {
const client = new ApolloClient({
ssrMode: true,
uri: process.env.NEXT_PUBLIC_NP_API_URL ?? 'https://api.dev.nodepen.io/graphql',
cache: new InMemoryCache(),
})

const { data } = await client.query({ query: QUEUE_STATUS, variables: { depth: 10 } })

const status = data.getQueueStatus

return {
props: {
solutionCount: status?.total_count,
userCount: status?.session_count,
},
}
}

export default Home
Loading

0 comments on commit 9b595f6

Please sign in to comment.