Skip to content

testkit-backend: extract request handlers to a separated file #636

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Nov 10, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
241 changes: 12 additions & 229 deletions testkit-backend/main.js
Original file line number Diff line number Diff line change
@@ -1,9 +1,7 @@
import neo4j from 'neo4j-driver'
import net from 'net'
import readline from 'readline'
import Context from './context.js'
import ResultObserver from './result-observer.js'
import { nativeToCypher, cypherToNative } from './cypher-native-binders.js'
import * as requestHandlers from './request-handlers.js'

class Backend {
constructor ({ writer }) {
Expand Down Expand Up @@ -50,234 +48,19 @@ class Backend {
request = JSON.parse(request)
const { name, data } = request
console.log('> Got request ' + name, data)
switch (name) {
case 'NewDriver':
{
const {
uri,
authorizationToken: { data: authToken },
userAgent
} = data
const driver = neo4j.driver(uri, authToken, { userAgent })
const id = this._context.addDriver(driver)
this._writeResponse('Driver', { id })
}
break

case 'DriverClose':
{
const { driverId } = data
const driver = this._context.getDriver(driverId)
driver
.close()
.then(() => {
this._writeResponse('Driver', { id: driverId })
})
.catch(err => this._writeError(err))
this._context.removeDriver(driverId)
}
break

case 'NewSession':
{
let { driverId, accessMode, bookmarks, database, fetchSize } = data
switch (accessMode) {
case 'r':
accessMode = neo4j.session.READ
break
case 'w':
accessMode = neo4j.session.WRITE
break
default:
this._writeBackendError('Unknown accessmode: ' + accessMode)
return
}
const driver = this._context.getDriver(driverId)
const session = driver.session({
defaultAccessMode: accessMode,
bookmarks,
database,
fetchSize
})
const id = this._context.addSession(session)
this._writeResponse('Session', { id })
}
break

case 'SessionClose':
{
const { sessionId } = data
const session = this._context.getSession(sessionId)
session
.close()
.then(() => {
this._writeResponse('Session', { id: sessionId })
})
.catch(err => this._writeError(err))
this._context.removeSession(sessionId)
}
break

case 'SessionRun':
{
const { sessionId, cypher, params, txMeta: metadata, timeout } = data
const session = this._context.getSession(sessionId)
if (params) {
for (const [key, value] of Object.entries(params)) {
params[key] = cypherToNative(value)
}
}

const observers = this._context.getResultObserversBySessionId(
sessionId
)

Promise.all(observers.map(obs => obs.completitionPromise()))
.catch(_ => null)
.then(_ => {
const result = session.run(cypher, params, { metadata, timeout })
const resultObserver = new ResultObserver({ sessionId })
result.subscribe(resultObserver)
const id = this._context.addResultObserver(resultObserver)
this._writeResponse('Result', { id })
})
}
break

case 'ResultNext':
{
const { resultId } = data
const resultObserver = this._context.getResultObserver(resultId)
const nextPromise = resultObserver.next()
nextPromise
.then(rec => {
if (rec) {
const values = Array.from(rec.values()).map(nativeToCypher)
this._writeResponse('Record', {
values: values
})
} else {
this._writeResponse('NullRecord', null)
}
})
.catch(e => {
console.log('got some err: ' + JSON.stringify(e))
this._writeError(e)
})
}
break

case 'SessionReadTransaction':
{
const { sessionId } = data
const session = this._context.getSession(sessionId)
session
.readTransaction(
tx =>
new Promise((resolve, reject) => {
const id = this._context.addTx(tx, sessionId, resolve, reject)
this._writeResponse('RetryableTry', { id })
})
)
.then(_ => this._writeResponse('RetryableDone', null))
.catch(error => this._writeError(error))
}
break

case 'TransactionRun':
{
const { txId, cypher, params } = data
const tx = this._context.getTx(txId)
if (params) {
for (const [key, value] of Object.entries(params)) {
params[key] = cypherToNative(value)
}
}
const result = tx.tx.run(cypher, params)
const resultObserver = new ResultObserver({})
result.subscribe(resultObserver)
const id = this._context.addResultObserver(resultObserver)
this._writeResponse('Result', { id })
}
break

case 'RetryablePositive':
{
const { sessionId } = data
this._context.getTxsBySessionId(sessionId).forEach(tx => {
tx.resolve()
this._context.removeTx(tx.id)
})
}
break

case 'RetryableNegative':
{
const { sessionId, errorId } = data
const error =
this._context.getError(errorId) || new Error('Client error')
this._context.getTxsBySessionId(sessionId).forEach(tx => {
tx.reject(error)
this._context.removeTx(tx.id)
})
}
break

case 'SessionBeginTransaction':
{
const { sessionId, txMeta: metadata, timeout } = data
const session = this._context.getSession(sessionId)
const tx = session.beginTransaction({ metadata, timeout })
const id = this._context.addTx(tx, sessionId)
this._writeResponse('Transaction', { id })
}
break

case 'TransactionCommit':
{
const { txId: id } = data
const { tx } = this._context.getTx(id)
tx.commit()
.then(() => this._writeResponse('Transaction', { id }))
.catch(e => {
console.log('got some err: ' + JSON.stringify(e))
this._writeError(e)
})
this._context.removeTx(id)
}
break

case 'SessionLastBookmarks':
{
const { sessionId } = data
const session = this._context.getSession(sessionId)
const bookmarks = session.lastBookmark()
this._writeResponse('Bookmarks', { bookmarks })
}
break

case 'SessionWriteTransaction':
{
const { sessionId } = data
const session = this._context.getSession(sessionId)
session
.writeTransaction(
tx =>
new Promise((resolve, reject) => {
const id = this._context.addTx(tx, sessionId, resolve, reject)
this._writeResponse('RetryableTry', { id })
})
)
.then(_ => this._writeResponse('RetryableDone', null))
.catch(error => this._writeError(error))
}
break

default:
this._writeBackendError('Unknown request: ' + name)
console.log('Unknown request: ' + name)
console.log(JSON.stringify(data))
if (name in requestHandlers) {
requestHandlers[name](this._context, data, {
writeResponse: this._writeResponse.bind(this),
writeError: this._writeError.bind(this),
writeBackendError: this._writeBackendError.bind(this)
})
return
}

this._writeBackendError('Unknown request: ' + name)
console.log('Unknown request: ' + name)
console.log(JSON.stringify(data))
}

_writeResponse (name, data) {
Expand Down
Loading