diff options
author | bob <bcz@cs.brown.edu> | 2019-04-03 11:45:15 -0400 |
---|---|---|
committer | bob <bcz@cs.brown.edu> | 2019-04-03 11:45:15 -0400 |
commit | bb7d5a26ec68f283c5adb42d4d6554253de7176f (patch) | |
tree | 7efa817102ba54e916601611f608dd4bd761a437 /src/client/Server.ts | |
parent | 43a0768690caa89c606dd5d296d3cc8825c1702b (diff) | |
parent | c406c8d123ce0aa9d63fb8a4dd90adfe83d2889d (diff) |
merged with master
Diffstat (limited to 'src/client/Server.ts')
-rw-r--r-- | src/client/Server.ts | 138 |
1 files changed, 98 insertions, 40 deletions
diff --git a/src/client/Server.ts b/src/client/Server.ts index f0cf0bb9b..37e3c2c0d 100644 --- a/src/client/Server.ts +++ b/src/client/Server.ts @@ -2,62 +2,115 @@ import { Key } from "../fields/Key" import { ObservableMap, action, reaction } from "mobx"; import { Field, FieldWaiting, FIELD_WAITING, Opt, FieldId } from "../fields/Field" import { Document } from "../fields/Document" -import { SocketStub } from "./SocketStub"; +import { SocketStub, FieldMap } from "./SocketStub"; import * as OpenSocket from 'socket.io-client'; import { Utils } from "./../Utils"; import { MessageStore, Types } from "./../server/Message"; export class Server { public static ClientFieldsCached: ObservableMap<FieldId, Field | FIELD_WAITING> = new ObservableMap(); - static Socket: SocketIOClient.Socket = OpenSocket(`${window.location.protocol}//${window.location.hostname}:1234`); + static Socket: SocketIOClient.Socket = OpenSocket(`${window.location.protocol}//${window.location.hostname}:4321`); static GUID: string = Utils.GenerateGuid() // Retrieves the cached value of the field and sends a request to the server for the real value (if it's not cached). // Call this is from within a reaction and test whether the return value is FieldWaiting. - // 'hackTimeout' is here temporarily for simplicity when debugging things. - public static GetField(fieldid: FieldId, callback: (field: Opt<Field>) => void): Opt<Field> | FIELD_WAITING { - let cached = this.ClientFieldsCached.get(fieldid); - if (!cached) { - this.ClientFieldsCached.set(fieldid, FieldWaiting); - SocketStub.SEND_FIELD_REQUEST(fieldid, action((field: Field | undefined) => { - let cached = this.ClientFieldsCached.get(fieldid); - if (cached != FieldWaiting) - callback(cached); - else { - if (field) { - this.ClientFieldsCached.set(fieldid, field); - } else { - this.ClientFieldsCached.delete(fieldid) + public static GetField(fieldid: FieldId): Promise<Opt<Field>>; + public static GetField(fieldid: FieldId, callback: (field: Opt<Field>) => void): void; + public static GetField(fieldid: FieldId, callback?: (field: Opt<Field>) => void): Promise<Opt<Field>> | void { + let fn = (cb: (field: Opt<Field>) => void) => { + + let cached = this.ClientFieldsCached.get(fieldid); + if (!cached) { + this.ClientFieldsCached.set(fieldid, FieldWaiting); + SocketStub.SEND_FIELD_REQUEST(fieldid, action((field: Field | undefined) => { + let cached = this.ClientFieldsCached.get(fieldid); + if (cached != FieldWaiting) + cb(cached); + else { + if (field) { + this.ClientFieldsCached.set(fieldid, field); + } else { + this.ClientFieldsCached.delete(fieldid) + } + cb(field) } - callback(field) - } - })); - } else if (cached != FieldWaiting) { - setTimeout(() => callback(cached as Field), 0); + })); + } else if (cached != FieldWaiting) { + setTimeout(() => cb(cached as Field), 0); + } else { + reaction(() => { + return this.ClientFieldsCached.get(fieldid); + }, (field, reaction) => { + if (field !== "<Waiting>") { + reaction.dispose() + cb(field) + } + }) + } + } + if (callback) { + fn(callback); } else { - reaction(() => { - return this.ClientFieldsCached.get(fieldid); - }, (field, reaction) => { - if (field !== "<Waiting>") { - callback(field) - reaction.dispose() - } - }) + return new Promise(res => fn(res)); } - return cached; } - public static GetFields(fieldIds: FieldId[], callback: (fields: { [id: string]: Field }) => any) { - SocketStub.SEND_FIELDS_REQUEST(fieldIds, (fields) => { - for (let key in fields) { - let field = fields[key]; - if (!this.ClientFieldsCached.has(field.Id)) { - this.ClientFieldsCached.set(field.Id, field) + public static GetFields(fieldIds: FieldId[]): Promise<{ [id: string]: Field }>; + public static GetFields(fieldIds: FieldId[], callback: (fields: FieldMap) => any): void; + public static GetFields(fieldIds: FieldId[], callback?: (fields: FieldMap) => any): Promise<FieldMap> | void { + let fn = (cb: (fields: FieldMap) => void) => { + + let neededFieldIds: FieldId[] = []; + let waitingFieldIds: FieldId[] = []; + let existingFields: { [id: string]: Field } = {}; + for (let id of fieldIds) { + let field = this.ClientFieldsCached.get(id); + if (!field) { + neededFieldIds.push(id); + this.ClientFieldsCached.set(id, FieldWaiting); + } else if (field === FieldWaiting) { + waitingFieldIds.push(id); + } else { + existingFields[id] = field; } } - callback(fields) - }); + SocketStub.SEND_FIELDS_REQUEST(neededFieldIds, action((fields: FieldMap) => { + for (let id of neededFieldIds) { + let field = fields[id]; + if (field) { + if (!(this.ClientFieldsCached.get(field.Id) instanceof Field)) { + this.ClientFieldsCached.set(field.Id, field) + } else { + throw new Error("we shouldn't be trying to replace things that are already in the cache") + } + } else { + if (this.ClientFieldsCached.get(id) === FieldWaiting) { + this.ClientFieldsCached.delete(id); + } else { + throw new Error("we shouldn't be trying to replace things that are already in the cache") + } + } + } + reaction(() => { + return waitingFieldIds.map(id => this.ClientFieldsCached.get(id)); + }, (cachedFields, reaction) => { + if (!cachedFields.some(field => !field || field === FieldWaiting)) { + reaction.dispose(); + for (let field of cachedFields) { + let realField = field as Field; + existingFields[realField.Id] = realField; + } + cb({ ...fields, ...existingFields }) + } + }, { fireImmediately: true }) + })); + }; + if (callback) { + fn(callback); + } else { + return new Promise(res => fn(res)); + } } public static GetDocumentField(doc: Document, key: Key, callback?: (field: Field) => void) { @@ -113,12 +166,17 @@ export class Server { if (Server.ClientFieldsCached.has(field._id)) { var f = Server.ClientFieldsCached.get(field._id); if (f && f != FieldWaiting) { + // console.log("Applying : " + field._id); f.UpdateFromServer(field.data); f.init(() => { }); + } else { + // console.log("Not applying wa : " + field._id); } + } else { + // console.log("Not applying mi : " + field._id); } } } -Server.Socket.on(MessageStore.Foo.Message, Server.connected); -Server.Socket.on(MessageStore.SetField.Message, Server.updateField);
\ No newline at end of file +Utils.AddServerHandler(Server.Socket, MessageStore.Foo, Server.connected); +Utils.AddServerHandler(Server.Socket, MessageStore.SetField, Server.updateField); |