2843 timeout on igc (#2846)

* chore: add timeout to tokenization call after message send

* chore: add timeout to IGC

* chore: add timeout to IT
pull/2245/head
ggurdin 6 months ago committed by GitHub
parent 3adac7f63c
commit 75f70c7fdb
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194

@ -400,7 +400,12 @@ class ChatView extends StatelessWidget {
// #Pangea
// Keep messages above minimum input bar height
if (!controller.room.isAbandonedDMRoom)
SizedBox(height: controller.inputBarHeight),
AnimatedSize(
duration: const Duration(milliseconds: 200),
child: SizedBox(
height: controller.inputBarHeight,
),
),
// Pangea#
],
),

@ -74,7 +74,8 @@ class ChatFloatingActionButtonState extends State<ChatFloatingActionButton> {
child: const Icon(Icons.arrow_downward_outlined),
);
}
if (widget.controller.choreographer.errorService.error != null) {
if (widget.controller.choreographer.errorService.error != null &&
!widget.controller.choreographer.itController.willOpen) {
return ChoreographerHasErrorButton(
widget.controller.choreographer.errorService.error!,
widget.controller.choreographer,

@ -1,3 +1,5 @@
import 'dart:async';
import 'package:flutter/material.dart';
import 'package:fluffychat/config/themes.dart';
@ -22,17 +24,27 @@ class ChatInputBar extends StatefulWidget {
}
class ChatInputBarState extends State<ChatInputBar> {
void updateHeight() {
final renderBox = context.findRenderObject() as RenderBox?;
if (renderBox == null || !renderBox.hasSize) return;
widget.controller.updateInputBarHeight(renderBox.size.height);
Timer? _debounceTimer;
void _updateHeight() {
_debounceTimer = Timer(const Duration(milliseconds: 100), () {
final renderBox = context.findRenderObject() as RenderBox?;
if (renderBox == null || !renderBox.hasSize) return;
widget.controller.updateInputBarHeight(renderBox.size.height);
});
}
@override
void dispose() {
_debounceTimer?.cancel();
super.dispose();
}
@override
Widget build(BuildContext context) {
return NotificationListener(
onNotification: (SizeChangedLayoutNotification notification) {
WidgetsBinding.instance.addPostFrameCallback((_) => updateHeight());
WidgetsBinding.instance.addPostFrameCallback((_) => _updateHeight());
return true;
},
child: SizeChangedLayoutNotifier(

@ -13,7 +13,6 @@ import 'package:fluffychat/pangea/choreographer/enums/edit_type.dart';
import 'package:fluffychat/pangea/choreographer/models/choreo_record.dart';
import 'package:fluffychat/pangea/choreographer/models/it_step.dart';
import 'package:fluffychat/pangea/choreographer/models/pangea_match_model.dart';
import 'package:fluffychat/pangea/choreographer/repo/language_detection_repo.dart';
import 'package:fluffychat/pangea/choreographer/utils/input_paste_listener.dart';
import 'package:fluffychat/pangea/choreographer/widgets/igc/pangea_text_controller.dart';
import 'package:fluffychat/pangea/choreographer/widgets/igc/paywall_card.dart';
@ -21,7 +20,6 @@ import 'package:fluffychat/pangea/common/controllers/pangea_controller.dart';
import 'package:fluffychat/pangea/common/utils/any_state_holder.dart';
import 'package:fluffychat/pangea/common/utils/error_handler.dart';
import 'package:fluffychat/pangea/common/utils/overlay.dart';
import 'package:fluffychat/pangea/events/models/pangea_token_model.dart';
import 'package:fluffychat/pangea/events/models/representation_content_model.dart';
import 'package:fluffychat/pangea/events/models/tokens_event_content_model.dart';
import 'package:fluffychat/pangea/events/repo/token_api_models.dart';
@ -148,56 +146,57 @@ class Choreographer {
)
: null;
final detectionResp = await LanguageDetectionRepo.get(
MatrixState.pangeaController.userController.accessToken,
request: LanguageDetectionRequest(
PangeaMessageTokens? tokensSent;
PangeaRepresentation? originalSent;
try {
TokensResponseModel? res;
if (l1LangCode != null && l2LangCode != null) {
res = await pangeaController.messageData
.getTokens(
repEventId: null,
room: chatController.room,
req: TokensRequestModel(
fullText: currentText,
senderL1: l1LangCode!,
senderL2: l2LangCode!,
),
)
.timeout(const Duration(seconds: 10));
}
originalSent = PangeaRepresentation(
langCode: res?.detections.firstOrNull?.langCode ??
LanguageKeys.unknownLanguage,
text: currentText,
senderl1: l1LangCode,
senderl2: l2LangCode,
),
);
final detections = detectionResp.detections;
final detectedLanguage =
detections.firstOrNull?.langCode ?? LanguageKeys.unknownLanguage;
final PangeaRepresentation originalSent = PangeaRepresentation(
langCode: detectedLanguage,
text: currentText,
originalSent: true,
originalWritten: originalWritten == null,
);
originalSent: true,
originalWritten: originalWritten == null,
);
List<PangeaToken>? res;
if (l1LangCode != null && l2LangCode != null) {
res = await pangeaController.messageData.getTokens(
repEventId: null,
room: chatController.room,
req: TokensRequestModel(
fullText: currentText,
langCode: detectedLanguage,
senderL1: l1LangCode!,
senderL2: l2LangCode!,
),
tokensSent = res != null
? PangeaMessageTokens(
tokens: res.tokens,
detections: res.detections,
)
: null;
} catch (e, s) {
ErrorHandler.logError(
e: e,
s: s,
data: {
"currentText": currentText,
"l1LangCode": l1LangCode,
"l2LangCode": l2LangCode,
"choreoRecord": choreoRecord.toJson(),
},
);
} finally {
chatController.send(
originalSent: originalSent,
tokensSent: tokensSent,
choreo: choreoRecord,
);
clear();
}
final PangeaMessageTokens? tokensSent = res != null
? PangeaMessageTokens(
tokens: res,
detections: detections,
)
: null;
chatController.send(
// originalWritten: originalWritten,
originalSent: originalSent,
tokensSent: tokensSent,
//TODO - save originalwritten tokens
// choreo: applicableChoreo,
choreo: choreoRecord,
);
clear();
}
_resetDebounceTimer() {

@ -104,7 +104,9 @@ class IgcController {
}
final IGCTextData igcTextDataResponse =
await _igcTextDataCache[reqBody.hashCode]!.data;
await _igcTextDataCache[reqBody.hashCode]!
.data
.timeout((const Duration(seconds: 10)));
// this will happen when the user changes the input while igc is fetching results
if (igcTextDataResponse.originalInput != choreographer.currentText) {

@ -57,7 +57,7 @@ class ITController {
choreographer.setState();
}
Duration get animationSpeed => const Duration(milliseconds: 500);
Duration get animationSpeed => const Duration(milliseconds: 300);
Future<void> initializeIT(ITStartData itStartData) async {
_willOpen = true;
@ -136,7 +136,8 @@ class ITController {
// During first IT step, next step will not be set
if (nextITStep == null) {
final ITResponseModel res = await _customInputTranslation(currentText);
final ITResponseModel res = await _customInputTranslation(currentText)
.timeout(const Duration(seconds: 10));
if (sourceText == null) return;
if (res.goldContinuances != null && res.goldContinuances!.isNotEmpty) {

@ -7,7 +7,6 @@ import 'package:flutter/material.dart';
import 'package:fluffychat/pangea/choreographer/constants/choreo_constants.dart';
import 'package:fluffychat/pangea/choreographer/controllers/choreographer.dart';
import 'package:fluffychat/pangea/choreographer/controllers/it_controller.dart';
import 'package:fluffychat/pangea/choreographer/widgets/it_bar_buttons.dart';
import 'package:fluffychat/pangea/choreographer/widgets/it_feedback_card.dart';
import 'package:fluffychat/pangea/common/utils/error_handler.dart';
import 'package:fluffychat/pangea/instructions/instructions_enum.dart';
@ -206,12 +205,14 @@ class ITBarState extends State<ITBar> with SingleTickerProviderStateMixin {
if (!itController.isEditingSourceText)
Padding(
padding: const EdgeInsets.only(top: 8.0),
child: itController.sourceText != null
? Text(
itController.sourceText!,
textAlign: TextAlign.center,
)
: const LinearProgressIndicator(),
child: !itController.willOpen
? const SizedBox()
: itController.sourceText != null
? Text(
itController.sourceText!,
textAlign: TextAlign.center,
)
: const LinearProgressIndicator(),
),
const SizedBox(height: 8.0),
Container(
@ -391,10 +392,12 @@ class ITChoices extends StatelessWidget {
return const SizedBox();
}
if (controller.currentITStep == null) {
return CircularProgressIndicator(
strokeWidth: 2.0,
color: Theme.of(context).colorScheme.primary,
);
return controller.willOpen
? CircularProgressIndicator(
strokeWidth: 2.0,
color: Theme.of(context).colorScheme.primary,
)
: const SizedBox();
}
return ChoicesArray(
id: controller.currentITStep.hashCode.toString(),
@ -438,23 +441,38 @@ class ITError extends StatelessWidget {
final ErrorCopy errorCopy = ErrorCopy(context, error);
return Padding(
padding: const EdgeInsets.symmetric(horizontal: 8),
child: Row(
mainAxisAlignment: MainAxisAlignment.center,
children: [
ConstrainedBox(
constraints: const BoxConstraints(maxWidth: 300),
child: Text(
// Text(
"${errorCopy.title}\n${errorCopy.body}",
// Haga clic en su mensaje para ver los significados de las palabras.
style: TextStyle(
fontStyle: FontStyle.italic,
child: RichText(
text: TextSpan(
children: [
WidgetSpan(
alignment: PlaceholderAlignment.middle,
child: Icon(
Icons.error_outline,
size: 20,
color: Theme.of(context).colorScheme.error,
),
),
TextSpan(text: " ${errorCopy.title} "),
WidgetSpan(
alignment: PlaceholderAlignment.middle,
child: IconButton(
onPressed: () {
controller.closeIT();
controller.choreographer.errorService.resetError();
},
icon: const Icon(
Icons.close,
size: 20,
),
),
),
],
style: TextStyle(
fontStyle: FontStyle.italic,
color: Theme.of(context).colorScheme.error,
),
ITRestartButton(controller: controller),
],
),
textAlign: TextAlign.center,
),
);
}

@ -1,27 +0,0 @@
import 'package:flutter/material.dart';
import 'package:fluffychat/pangea/common/controllers/pangea_controller.dart';
import 'package:fluffychat/widgets/matrix.dart';
import '../controllers/it_controller.dart';
class ITRestartButton extends StatelessWidget {
ITRestartButton({
super.key,
required this.controller,
});
final ITController controller;
final PangeaController pangeaController = MatrixState.pangeaController;
@override
Widget build(BuildContext context) {
return IconButton(
onPressed: () async {
controller.choreographer.errorService.resetError();
controller.currentITStep = null;
controller.choreographer.getLanguageHelp();
},
icon: const Icon(Icons.refresh_outlined),
);
}
}

@ -12,7 +12,6 @@ import 'package:fluffychat/pangea/common/controllers/pangea_controller.dart';
import 'package:fluffychat/pangea/common/utils/error_handler.dart';
import 'package:fluffychat/pangea/events/constants/pangea_event_types.dart';
import 'package:fluffychat/pangea/events/event_wrappers/pangea_message_event.dart';
import 'package:fluffychat/pangea/events/models/pangea_token_model.dart';
import 'package:fluffychat/pangea/events/models/representation_content_model.dart';
import 'package:fluffychat/pangea/events/models/tokens_event_content_model.dart';
import 'package:fluffychat/pangea/events/repo/token_api_models.dart';
@ -23,7 +22,7 @@ import 'package:fluffychat/pangea/extensions/pangea_room_extension.dart';
class MessageDataController extends BaseController {
late PangeaController _pangeaController;
final Map<int, Future<List<PangeaToken>>> _tokensCache = {};
final Map<int, Future<TokensResponseModel>> _tokensCache = {};
final Map<int, Future<PangeaRepresentation>> _representationCache = {};
late Timer _cacheTimer;
@ -54,7 +53,7 @@ class MessageDataController extends BaseController {
/// get tokens from the server
/// if repEventId is not null, send the tokens to the room
Future<List<PangeaToken>> _getTokens({
Future<TokensResponseModel> _getTokens({
required String? repEventId,
required TokensRequestModel req,
required Room? room,
@ -83,13 +82,13 @@ class MessageDataController extends BaseController {
);
}
return res.tokens;
return res;
}
/// get tokens from the server
/// first check if the tokens are in the cache
/// if repEventId is not null, send the tokens to the room
Future<List<PangeaToken>> getTokens({
Future<TokensResponseModel> getTokens({
required String? repEventId,
required TokensRequestModel req,
required Room? room,

@ -162,7 +162,7 @@ class RepresentationEvent {
),
);
}
final List<PangeaToken> res =
final TokensResponseModel res =
await MatrixState.pangeaController.messageData.getTokens(
repEventId: _event?.eventId,
room: _event?.room ?? parentMessageEvent.room,
@ -180,7 +180,7 @@ class RepresentationEvent {
),
);
return res;
return res.tokens;
}
Future<void> sendTokensEvent(

@ -1,6 +1,7 @@
import 'package:fluffychat/pangea/choreographer/models/language_detection_model.dart';
import 'package:fluffychat/pangea/common/constants/model_keys.dart';
import 'package:fluffychat/pangea/events/models/pangea_token_model.dart';
import 'package:fluffychat/pangea/learning_settings/constants/language_constants.dart';
class TokensRequestModel {
/// the text to be tokenized
@ -24,16 +25,16 @@ class TokensRequestModel {
TokensRequestModel({
required this.fullText,
required this.langCode,
required this.senderL1,
required this.senderL2,
this.langCode,
});
Map<String, dynamic> toJson() => {
ModelKey.fullText: fullText,
ModelKey.userL1: senderL1,
ModelKey.userL2: senderL2,
ModelKey.langCode: langCode,
ModelKey.langCode: langCode ?? LanguageKeys.unknownLanguage,
};
// override equals and hashcode

Loading…
Cancel
Save