Skip to content
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

Add support for external storages on lock, unlock, update, get, and delete #654

Merged
2 changes: 2 additions & 0 deletions hub-js/proto/storage_backend.proto
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ message OnUpdateRequest {
uint32 new_resource_version = 2;
bytes new_value = 3;
optional bytes context = 4;
optional string owner_id = 5;
}

message OnUpdateResponse {
Expand All @@ -31,6 +32,7 @@ message OnUpdateResponse {
message OnDeleteRequest {
string type_instance_id = 1;
optional bytes context = 2;
optional string owner_id = 3;
}

message OnDeleteResponse {}
Expand Down
23 changes: 22 additions & 1 deletion hub-js/src/generated/grpc/storage_backend.ts
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ export interface OnUpdateRequest {
newResourceVersion: number;
newValue: Uint8Array;
context?: Uint8Array | undefined;
ownerId?: string | undefined;
}

export interface OnUpdateResponse {
Expand All @@ -33,6 +34,7 @@ export interface OnUpdateResponse {
export interface OnDeleteRequest {
typeInstanceId: string;
context?: Uint8Array | undefined;
ownerId?: string | undefined;
}

export interface OnDeleteResponse {}
Expand Down Expand Up @@ -293,6 +295,7 @@ function createBaseOnUpdateRequest(): OnUpdateRequest {
newResourceVersion: 0,
newValue: new Uint8Array(),
context: undefined,
ownerId: undefined,
};
}

Expand All @@ -313,6 +316,9 @@ export const OnUpdateRequest = {
if (message.context !== undefined) {
writer.uint32(34).bytes(message.context);
}
if (message.ownerId !== undefined) {
writer.uint32(42).string(message.ownerId);
}
return writer;
},

Expand All @@ -335,6 +341,9 @@ export const OnUpdateRequest = {
case 4:
message.context = reader.bytes();
break;
case 5:
message.ownerId = reader.string();
break;
default:
reader.skipType(tag & 7);
break;
Expand All @@ -357,6 +366,7 @@ export const OnUpdateRequest = {
context: isSet(object.context)
? bytesFromBase64(object.context)
: undefined,
ownerId: isSet(object.ownerId) ? String(object.ownerId) : undefined,
};
},

Expand All @@ -375,6 +385,7 @@ export const OnUpdateRequest = {
message.context !== undefined
? base64FromBytes(message.context)
: undefined);
message.ownerId !== undefined && (obj.ownerId = message.ownerId);
return obj;
},

Expand All @@ -384,6 +395,7 @@ export const OnUpdateRequest = {
message.newResourceVersion = object.newResourceVersion ?? 0;
message.newValue = object.newValue ?? new Uint8Array();
message.context = object.context ?? undefined;
message.ownerId = object.ownerId ?? undefined;
return message;
},
};
Expand Down Expand Up @@ -447,7 +459,7 @@ export const OnUpdateResponse = {
};

function createBaseOnDeleteRequest(): OnDeleteRequest {
return { typeInstanceId: "", context: undefined };
return { typeInstanceId: "", context: undefined, ownerId: undefined };
}

export const OnDeleteRequest = {
Expand All @@ -461,6 +473,9 @@ export const OnDeleteRequest = {
if (message.context !== undefined) {
writer.uint32(18).bytes(message.context);
}
if (message.ownerId !== undefined) {
writer.uint32(26).string(message.ownerId);
}
return writer;
},

Expand All @@ -477,6 +492,9 @@ export const OnDeleteRequest = {
case 2:
message.context = reader.bytes();
break;
case 3:
message.ownerId = reader.string();
break;
default:
reader.skipType(tag & 7);
break;
Expand All @@ -493,6 +511,7 @@ export const OnDeleteRequest = {
context: isSet(object.context)
? bytesFromBase64(object.context)
: undefined,
ownerId: isSet(object.ownerId) ? String(object.ownerId) : undefined,
};
},

Expand All @@ -505,13 +524,15 @@ export const OnDeleteRequest = {
message.context !== undefined
? base64FromBytes(message.context)
: undefined);
message.ownerId !== undefined && (obj.ownerId = message.ownerId);
return obj;
},

fromPartial(object: DeepPartial<OnDeleteRequest>): OnDeleteRequest {
const message = createBaseOnDeleteRequest();
message.typeInstanceId = object.typeInstanceId ?? "";
message.context = object.context ?? undefined;
message.ownerId = object.ownerId ?? undefined;
return message;
},
};
Expand Down
4 changes: 2 additions & 2 deletions hub-js/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ import { config } from "./config";
import { logger } from "./logger";
import { ensureCoreStorageTypeInstance } from "./local/resolver/mutation/register-built-in-storage";
import DelegatedStorageService from "./local/storage/service";
import UpdateArgsContext from "./local/storage/update-args-context";
import UpdateArgsContainer from "./local/storage/update-args-container";

async function main() {
logger.info("Using Neo4j database", { endpoint: config.neo4j.endpoint });
Expand Down Expand Up @@ -73,7 +73,7 @@ async function setupHttpServer(
return {
driver,
delegatedStorage,
updateArgs: new UpdateArgsContext(),
updateArgs: new UpdateArgsContainer(),
};
},
});
Expand Down
4 changes: 3 additions & 1 deletion hub-js/src/local/resolver/field/spec-value-field.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { logger } from "../../../logger";
import { GetInput } from "../../storage/service";
import { Context } from "../mutation/context";
import { Operation } from "../../storage/update-args-context";
import { Operation } from "../../storage/update-args-container";
import _ from "lodash";
import { Mutex } from "async-mutex";

Expand Down Expand Up @@ -87,13 +87,15 @@ async function resolveMutationReturnValue(
newValue = resp[tiId];
}

console.log(context.updateArgs.GetOwnerID(fetchInput.typeInstance.id));
mszostok marked this conversation as resolved.
Show resolved Hide resolved
// 2. Update TypeInstance's value
const update = {
backend: fetchInput.backend,
typeInstance: {
id: fetchInput.typeInstance.id,
newResourceVersion: fetchInput.typeInstance.resourceVersion,
newValue,
ownerID: context.updateArgs.GetOwnerID(fetchInput.typeInstance.id),
},
};

Expand Down
4 changes: 2 additions & 2 deletions hub-js/src/local/resolver/mutation/context.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { Driver } from "neo4j-driver";
import DelegatedStorageService from "../../storage/service";
import UpdateArgsContext from "../../storage/update-args-context";
import UpdateArgsContainer from "../../storage/update-args-container";

export interface ContextWithDriver {
driver: Driver;
Expand All @@ -11,7 +11,7 @@ export interface ContextWithDelegatedStorage {
}

export interface ContextWithUpdateArgs {
updateArgs: UpdateArgsContext;
updateArgs: UpdateArgsContainer;
}

export interface Context
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ interface CreateTypeInstanceArgs {
}

export async function createTypeInstance(
_: undefined,
_: unknown,
args: CreateTypeInstanceArgs,
context: Context
) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@ export type TypeInstanceInput = Omit<CreateTypeInstanceInput, "backend"> & {
};

export async function createTypeInstances(
_: undefined,
_: unknown,
args: CreateTypeInstancesArgs,
context: Context
) {
Expand Down
9 changes: 5 additions & 4 deletions hub-js/src/local/resolver/mutation/delete-type-instance.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,10 @@ import {
tryToExtractCustomCypherError,
} from "./cypher-errors";
import { logger } from "../../../logger";
import { TypeInstanceBackendInput } from "../../types/type-instance";

export async function deleteTypeInstance(
_: undefined,
_: unknown,
args: { id: string; ownerID: string },
context: Context
) {
Expand Down Expand Up @@ -89,8 +90,7 @@ export async function deleteTypeInstance(
);

// NOTE: Use map to ensure that external storage is not called multiple time for the same ID
// eslint-disable-next-line @typescript-eslint/no-explicit-any
const deleteExternally = new Map<string, any>();
const deleteExternally = new Map<string, unknown>();
result.records.forEach((record) => {
const out = record.get("out");

Expand All @@ -104,8 +104,9 @@ export async function deleteTypeInstance(
await context.delegatedStorage.Delete({
typeInstance: {
id,
ownerID: args.ownerID,
},
backend,
backend: backend as TypeInstanceBackendInput,
});
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ interface ExternallyStoredOutput {
}

export async function lockTypeInstances(
_: undefined,
_: unknown,
args: LockingTypeInstanceInput,
context: Context
) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ import { logger } from "../../../logger";
interface UnLockTypeInstanceInput extends LockingTypeInstanceInput {}

export async function unlockTypeInstances(
_: undefined,
_: unknown,
args: UnLockTypeInstanceInput,
context: Context
) {
Expand Down
8 changes: 5 additions & 3 deletions hub-js/src/local/resolver/mutation/update-type-instances.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,21 +9,22 @@ import {
} from "./cypher-errors";
import { logger } from "../../../logger";
import { Context } from "./context";
import { Operation } from "../../storage/update-args-context";
import { Operation } from "../../storage/update-args-container";

interface UpdateTypeInstancesInput {
in: [
{
id: string;
ownerID?: string;
typeInstance: {
value?: undefined;
value?: unknown;
};
}
];
}

export async function updateTypeInstances(
_: undefined,
_: unknown,
args: UpdateTypeInstancesInput,
context: Context,
resolveInfo: GraphQLResolveInfo
Expand All @@ -33,6 +34,7 @@ export async function updateTypeInstances(
context.updateArgs.SetOperation(Operation.UpdateTypeInstancesMutation);
args.in.forEach((x) => {
context.updateArgs.SetValue(x.id, x.typeInstance.value);
context.updateArgs.SetOwnerID(x.id, x.ownerID);
});

const neo4jSession = context.driver.session();
Expand Down
21 changes: 10 additions & 11 deletions hub-js/src/local/storage/service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -28,8 +28,7 @@ export interface StoreInput {
backend: TypeInstanceBackendInput;
typeInstance: {
id: string;
// eslint-disable-next-line @typescript-eslint/no-explicit-any
value: any;
value: unknown;
};
}

Expand All @@ -38,8 +37,8 @@ export interface UpdateInput {
typeInstance: {
id: string;
newResourceVersion: number;
// eslint-disable-next-line @typescript-eslint/no-explicit-any
newValue: any;
newValue: unknown;
ownerID?: string;
};
}

Expand All @@ -55,6 +54,7 @@ export interface DeleteInput {
backend: TypeInstanceBackendInput;
typeInstance: {
id: string;
ownerID?: string;
};
}

Expand All @@ -74,8 +74,7 @@ export interface UnlockInput {
}

export interface UpdatedContexts {
// eslint-disable-next-line @typescript-eslint/no-explicit-any
[key: string]: any;
[key: string]: unknown;
}

export default class DelegatedStorageService {
Expand Down Expand Up @@ -158,6 +157,7 @@ export default class DelegatedStorageService {
newResourceVersion: input.typeInstance.newResourceVersion,
newValue: this.encode(input.typeInstance.newValue),
context: this.encode(input.backend.context),
ownerId: input.typeInstance.ownerID,
};

await cli.onUpdate(req);
Expand Down Expand Up @@ -236,6 +236,7 @@ export default class DelegatedStorageService {
const req: OnDeleteRequest = {
typeInstanceId: input.typeInstance.id,
context: this.encode(input.backend.context),
ownerId: input.typeInstance.ownerID,
};
await cli.onDelete(req);
}
Expand Down Expand Up @@ -362,16 +363,14 @@ export default class DelegatedStorageService {
return this.registeredClients.get(id);
}

// eslint-disable-next-line @typescript-eslint/no-explicit-any
private static convertToJSONIfObject(val: any) {
private static convertToJSONIfObject(val: unknown): string | undefined {
if (val instanceof Array || typeof val === "object") {
return JSON.stringify(val);
}
return val;
return val as string;
}

// eslint-disable-next-line @typescript-eslint/no-explicit-any
private encode(val: any) {
private encode(val: unknown) {
return new TextEncoder().encode(
DelegatedStorageService.convertToJSONIfObject(val)
);
Expand Down
Loading