diff --git a/src/components/views/rooms/MessageComposer.js b/src/components/views/rooms/MessageComposer.js index 6c227458aa..7750a2f201 100644 --- a/src/components/views/rooms/MessageComposer.js +++ b/src/components/views/rooms/MessageComposer.js @@ -337,7 +337,7 @@ export default class MessageComposer extends React.Component { const recording = VoiceRecordingStore.instance.activeRecording; this.setState({haveRecording: !!recording}); if (recording) { - // We show a little head's up that the recording is about to automatically end soon. The 3s + // We show a little heads up that the recording is about to automatically end soon. The 3s // display time is completely arbitrary. Note that we don't need to deregister the listener // because the recording instance will clean that up for us. recording.on(RecordingState.EndingSoon, ({secondsLeft}) => { diff --git a/src/utils/Singleflight.ts b/src/utils/Singleflight.ts index c8d303bcac..1c2af4278d 100644 --- a/src/utils/Singleflight.ts +++ b/src/utils/Singleflight.ts @@ -23,6 +23,22 @@ const keyMap = new EnhancedMap>(); /** * Access class to get a singleflight context. Singleflights execute a * function exactly once, unless instructed to forget about a result. + * + * Typically this is used to de-duplicate an action, such as a save button + * being pressed, without having to track state internally for an operation + * already being in progress. This doesn't expose a flag which can be used + * to disable a button, however it would be capable of returning a Promise + * from the first call. + * + * The result of the function call are cached indefinitely, just in case a + * second call comes through late. There are various functions named "forget" + * to have the cache be cleared of a result. + * + * Singleflights in our usecase are tied to an instance of something, combined + * with a string key to differentiate between multiple possible actions. This + * means that a "save" key will be scoped to the instance which defined it and + * not leak between other instances. This is done to avoid having to concatenate + * variables to strings to essentially namespace the field, for most cases. */ export class Singleflight { private constructor() { @@ -83,6 +99,15 @@ class SingleflightContext { * will be called, with its return value cached. The function must return a value * other than `undefined` - take a look at Singleflight.Void if you don't have a return * to make. + * + * Note that this technically allows the caller to provide a different function each time: + * this is largely considered a bad idea and should not be done. Singleflights work off the + * premise that something needs to happen once, so duplicate executions will be ignored. + * + * For ideal performance and behaviour, functions which return promises are preferred. If + * a function is not returning a promise, it should return as soon as possible to avoid a + * second call potentially racing it. The promise returned by this function will be that + * of the first execution of the function, even on duplicate calls. * @param {Function} fn The function to execute. * @returns The recorded value. */