aws-amplify / amplify-android

The fastest and easiest way to use AWS from your Android app.
https://docs.amplify.aws/lib/q/platform/android/
Apache License 2.0
246 stars 115 forks source link

Unable to acquire orchestrator lock. Transition currently in progress. #1010

Closed renebrandel closed 11 months ago

renebrandel commented 3 years ago

While creating M:N relationships, I get an error:

Unable to acquire orchestrator lock. Transition currently in progress.

@jamesonwilliams suggested a work-around to require a DataStore. READY event to be set before relationship creation. We agreed the work-around shouldn't be necessary.

When I run this code:

Content content = Content.builder()
    .body("Hello from Android13")
     .build();

Tag tag = Tag.builder()
    .label("Test 123123-12313")
    .build();

ContentTag contentTag = ContentTag.builder()
    .content(content)
    .tag(tag)
    .build();

Amplify.DataStore.save(content,
    savedPost -> {
        Log.i("MyAmplifyApp", "Content saved.");
        Amplify.DataStore.save(tag,
            savedEditor -> {
                Log.i("MyAmplifyApp", "Tag saved.");
                Amplify.DataStore.save(contentTag,
                    saved -> Log.i("MyAmplifyApp", "ContentTag saved."),
                    failure -> Log.e("MyAmplifyApp", "ContentTag not saved.", failure)
                );
            },
            failure -> Log.e("MyAmplifyApp", "Tag not saved.", failure)
        );
    },
    failure -> Log.e("MyAmplifyApp", "Content not saved.", failure)
);

I get this crash:

2020-11-30 11:18:15.800 15077-15118/com.example.relationshipjava I/MyAmplifyApp: Content saved.
2020-11-30 11:18:17.820 15077-15120/com.example.relationshipjava E/MyAmplifyApp: Tag not saved.
    DataStoreException{message=Unable to acquire orchestrator lock. Transition currently in progress., cause=null, recoverySuggestion=Retry your request}
        at com.amplifyframework.datastore.syncengine.Orchestrator.start(Orchestrator.java:195)
        at com.amplifyframework.datastore.AWSDataStorePlugin.lambda$start$9$AWSDataStorePlugin(AWSDataStorePlugin.java:259)
        at com.amplifyframework.datastore.-$$Lambda$AWSDataStorePlugin$FPjeqf-ENbST6bEgtzMenBBWB54.call(Unknown Source:6)
        at com.amplifyframework.datastore.-$$Lambda$TpN5VBwI7X4qLhZPz2Xh_RciFYY.run(Unknown Source:2)
        at io.reactivex.rxjava3.internal.observers.CallbackCompletableObserver.onComplete(CallbackCompletableObserver.java:53)
        at io.reactivex.rxjava3.internal.operators.completable.CompletableSubscribeOn$SubscribeOnObserver.onComplete(CompletableSubscribeOn.java:79)
        at io.reactivex.rxjava3.internal.operators.completable.CompletableTimeout$TimeOutObserver.onComplete(CompletableTimeout.java:87)
        at io.reactivex.rxjava3.internal.operators.completable.CompletableCreate$Emitter.onComplete(CompletableCreate.java:65)
        at com.amplifyframework.datastore.AWSDataStorePlugin.lambda$waitForInitialization$7$AWSDataStorePlugin(AWSDataStorePlugin.java:241)
        at com.amplifyframework.datastore.-$$Lambda$AWSDataStorePlugin$F7opBt57ZUb5PGbudjZ5clNE1H8.subscribe(Unknown Source:2)
        at io.reactivex.rxjava3.internal.operators.completable.CompletableCreate.subscribeActual(CompletableCreate.java:40)
        at io.reactivex.rxjava3.core.Completable.subscribe(Completable.java:2850)
        at io.reactivex.rxjava3.internal.operators.completable.CompletableTimeout.subscribeActual(CompletableTimeout.java:53)
        at io.reactivex.rxjava3.core.Completable.subscribe(Completable.java:2850)
        at io.reactivex.rxjava3.internal.operators.completable.CompletableSubscribeOn$SubscribeOnObserver.run(CompletableSubscribeOn.java:64)
        at io.reactivex.rxjava3.core.Scheduler$DisposeTask.run(Scheduler.java:614)
        at io.reactivex.rxjava3.internal.schedulers.ScheduledRunnable.run(ScheduledRunnable.java:65)
        at io.reactivex.rxjava3.internal.schedulers.ScheduledRunnable.call(ScheduledRunnable.java:56)
        at java.util.concurrent.FutureTask.run(FutureTask.java:266)
        at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.run(ScheduledThreadPoolExecutor.java:301)
        at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1167)
        at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:641)
        at java.lang.Thread.run(Thread.java:919)
jamesonwilliams commented 3 years ago

@richardmcclellan was working on this as of this morning. @richardmcclellan are we tracking this in another issue already -- should we close this as as duplicate?

The workaround I proposed was to do:

Amplify.DataStore.subscribe(HubChannel.DataStore,
    { DataStoreChannelEventName.READY.toString() == it.name },
    { startUsingDataStore() }
)

fun startUsingDataStore() {
    // Call your code above, here.
}

This is a workaround until we fix the bug.

oras commented 3 years ago

cause=DataStoreException{message=Timed out acquiring orchestrator lock., cause=null, recoverySuggestion=Retry your request.}, recoverySuggestion=Retry.}

rakeshdas369 commented 3 years ago

I/amplify:aws-datastore(12127): Orchestrator lock acquired. I/amplify:aws-datastore(12127): Orchestrator lock released. E/amplify:flutter:datastore(12127): Save operation failed E/amplify:flutter:datastore(12127): DataStoreException{message=Error in saving the model: MemberDetailsModel[id=ed81ad35-6ec2-4e3c-af6e-d3a9727ab295], cause=java.lang.NullPointerException, recoverySuggestion=See attached exception for details.} E/amplify:flutter:datastore(12127): at com.amplifyframework.datastore.storage.sqlite.SQLiteStorageAdapter.lambda$save$3$SQLiteStorageAdapter(SQLiteStorageAdapter.java:331) E/amplify:flutter:datastore(12127): at com.amplifyframework.datastore.storage.sqlite.-$$Lambda$SQLiteStorageAdapter$0Q4t2Se5oVsIb4pxkwWPcTH3ADs.run(Unknown Source:12) E/amplify:flutter:datastore(12127): at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:458) E/amplify:flutter:datastore(12127): at java.util.concurrent.FutureTask.run(FutureTask.java:266) E/amplify:flutter:datastore(12127): at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1167) E/amplify:flutter:datastore(12127): at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:641) E/amplify:flutter:datastore(12127): at java.lang.Thread.run(Thread.java:764) E/amplify:flutter:datastore(12127): Caused by: java.lang.NullPointerException E/amplify:flutter:datastore(12127): at java.util.Objects.requireNonNull(Objects.java:203) E/amplify:flutter:datastore(12127): at com.amplifyframework.datastore.storage.sqlite.adapter.SQLiteTable.fromSchema(SQLiteTable.java:81) E/amplify:flutter:datastore(12127): at com.amplifyframework.datastore.storage.sqlite.SQLiteStorageAdapter.modelExists(SQLiteStorageAdapter.java:749)

***could anybody help me to resolve it*

ntalamdotcom commented 2 years ago

2022, I am still seeing this error

ghost commented 2 years ago

I'm still seeing this error x2

Any updated?

ghost commented 2 years ago

Any updated?

chrisbonifacio commented 2 years ago

@ntalamdotcom @3nd3rs0nn curious what version of Amplify and the shape of your schemas? Please let us know so that we can reproduce this internally. If not on the latest version already, please upgrade and let us know if the issue still persists.

ghost commented 2 years ago

@chrisbonifacio I'm using

amplify_core: 0.6.6
amplify_flutter: 0.6.6
amplify_auth_cognito: 0.6.6
amplify_api: 0.6.6
amplify_datastore: 0.6.6

This is an example of one of the models I'm using:

/*
* Copyright 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License").
* You may not use this file except in compliance with the License.
* A copy of the License is located at
*
*  http://aws.amazon.com/apache2.0
*
* or in the "license" file accompanying this file. This file is distributed
* on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
* express or implied. See the License for the specific language governing
* permissions and limitations under the License.
*/

// NOTE: This file is generated and may not follow lint rules defined in your app
// Generated files can be excluded from analysis in analysis_options.yaml
// For more info, see: https://dart.dev/guides/language/analysis-options#excluding-code-from-analysis

// ignore_for_file: public_member_api_docs, annotate_overrides, dead_code, dead_codepublic_member_api_docs, depend_on_referenced_packages, file_names, library_private_types_in_public_api, no_leading_underscores_for_library_prefixes, no_leading_underscores_for_local_identifiers, non_constant_identifier_names, null_check_on_nullable_type_parameter, prefer_adjacent_string_concatenation, prefer_const_constructors, prefer_if_null_operators, prefer_interpolation_to_compose_strings, slash_for_doc_comments, sort_child_properties_last, unnecessary_const, unnecessary_constructor_name, unnecessary_late, unnecessary_new, unnecessary_null_aware_assignments, unnecessary_nullable_for_final_variable_declarations, unnecessary_string_interpolations, use_build_context_synchronously

import 'package:amplify_core/amplify_core.dart';
import 'package:collection/collection.dart';
import 'package:flutter/foundation.dart';

/** This is an auto generated class representing the AddMoreEvidence type in your schema. */
@immutable
class AddMoreEvidence extends Model {
  static const classType = const _AddMoreEvidenceModelType();
  final String id;
  final int? _deliveryRoutePointId;
  final List<String>? _evidences;
  final int? _deliveryRouteId;
  final int? _deliveryRoutePointStateId;
  final TemporalDateTime? _createdAt;
  final TemporalDateTime? _updatedAt;

  @override
  getInstanceType() => classType;

  @override
  String getId() {
    return id;
  }

  int get deliveryRoutePointId {
    try {
      return _deliveryRoutePointId!;
    } catch(e) {
      throw new AmplifyCodeGenModelException(
          AmplifyExceptionMessages.codeGenRequiredFieldForceCastExceptionMessage,
          recoverySuggestion:
            AmplifyExceptionMessages.codeGenRequiredFieldForceCastRecoverySuggestion,
          underlyingException: e.toString()
          );
    }
  }

  List<String>? get evidences {
    return _evidences;
  }

  int get deliveryRouteId {
    try {
      return _deliveryRouteId!;
    } catch(e) {
      throw new AmplifyCodeGenModelException(
          AmplifyExceptionMessages.codeGenRequiredFieldForceCastExceptionMessage,
          recoverySuggestion:
            AmplifyExceptionMessages.codeGenRequiredFieldForceCastRecoverySuggestion,
          underlyingException: e.toString()
          );
    }
  }

  int get deliveryRoutePointStateId {
    try {
      return _deliveryRoutePointStateId!;
    } catch(e) {
      throw new AmplifyCodeGenModelException(
          AmplifyExceptionMessages.codeGenRequiredFieldForceCastExceptionMessage,
          recoverySuggestion:
            AmplifyExceptionMessages.codeGenRequiredFieldForceCastRecoverySuggestion,
          underlyingException: e.toString()
          );
    }
  }

  TemporalDateTime? get createdAt {
    return _createdAt;
  }

  TemporalDateTime? get updatedAt {
    return _updatedAt;
  }

  const AddMoreEvidence._internal({required this.id, required deliveryRoutePointId, evidences, required deliveryRouteId, required deliveryRoutePointStateId, createdAt, updatedAt}): _deliveryRoutePointId = deliveryRoutePointId, _evidences = evidences, _deliveryRouteId = deliveryRouteId, _deliveryRoutePointStateId = deliveryRoutePointStateId, _createdAt = createdAt, _updatedAt = updatedAt;

  factory AddMoreEvidence({String? id, required int deliveryRoutePointId, List<String>? evidences, required int deliveryRouteId, required int deliveryRoutePointStateId}) {
    return AddMoreEvidence._internal(
      id: id == null ? UUID.getUUID() : id,
      deliveryRoutePointId: deliveryRoutePointId,
      evidences: evidences != null ? List<String>.unmodifiable(evidences) : evidences,
      deliveryRouteId: deliveryRouteId,
      deliveryRoutePointStateId: deliveryRoutePointStateId);
  }

  bool equals(Object other) {
    return this == other;
  }

  @override
  bool operator ==(Object other) {
    if (identical(other, this)) return true;
    return other is AddMoreEvidence &&
      id == other.id &&
      _deliveryRoutePointId == other._deliveryRoutePointId &&
      DeepCollectionEquality().equals(_evidences, other._evidences) &&
      _deliveryRouteId == other._deliveryRouteId &&
      _deliveryRoutePointStateId == other._deliveryRoutePointStateId;
  }

  @override
  int get hashCode => toString().hashCode;

  @override
  String toString() {
    var buffer = new StringBuffer();

    buffer.write("AddMoreEvidence {");
    buffer.write("id=" + "$id" + ", ");
    buffer.write("deliveryRoutePointId=" + (_deliveryRoutePointId != null ? _deliveryRoutePointId!.toString() : "null") + ", ");
    buffer.write("evidences=" + (_evidences != null ? _evidences!.toString() : "null") + ", ");
    buffer.write("deliveryRouteId=" + (_deliveryRouteId != null ? _deliveryRouteId!.toString() : "null") + ", ");
    buffer.write("deliveryRoutePointStateId=" + (_deliveryRoutePointStateId != null ? _deliveryRoutePointStateId!.toString() : "null") + ", ");
    buffer.write("createdAt=" + (_createdAt != null ? _createdAt!.format() : "null") + ", ");
    buffer.write("updatedAt=" + (_updatedAt != null ? _updatedAt!.format() : "null"));
    buffer.write("}");

    return buffer.toString();
  }

  AddMoreEvidence copyWith({String? id, int? deliveryRoutePointId, List<String>? evidences, int? deliveryRouteId, int? deliveryRoutePointStateId}) {
    return AddMoreEvidence._internal(
      id: id ?? this.id,
      deliveryRoutePointId: deliveryRoutePointId ?? this.deliveryRoutePointId,
      evidences: evidences ?? this.evidences,
      deliveryRouteId: deliveryRouteId ?? this.deliveryRouteId,
      deliveryRoutePointStateId: deliveryRoutePointStateId ?? this.deliveryRoutePointStateId);
  }

  AddMoreEvidence.fromJson(Map<String, dynamic> json)  
    : id = json['id'],
      _deliveryRoutePointId = (json['deliveryRoutePointId'] as num?)?.toInt(),
      _evidences = json['evidences']?.cast<String>(),
      _deliveryRouteId = (json['deliveryRouteId'] as num?)?.toInt(),
      _deliveryRoutePointStateId = (json['deliveryRoutePointStateId'] as num?)?.toInt(),
      _createdAt = json['createdAt'] != null ? TemporalDateTime.fromString(json['createdAt']) : null,
      _updatedAt = json['updatedAt'] != null ? TemporalDateTime.fromString(json['updatedAt']) : null;

  Map<String, dynamic> toJson() => {
    'id': id, 'deliveryRoutePointId': _deliveryRoutePointId, 'evidences': _evidences, 'deliveryRouteId': _deliveryRouteId, 'deliveryRoutePointStateId': _deliveryRoutePointStateId, 'createdAt': _createdAt?.format(), 'updatedAt': _updatedAt?.format()
  };

  static final QueryField ID = QueryField(fieldName: "id");
  static final QueryField DELIVERYROUTEPOINTID = QueryField(fieldName: "deliveryRoutePointId");
  static final QueryField EVIDENCES = QueryField(fieldName: "evidences");
  static final QueryField DELIVERYROUTEID = QueryField(fieldName: "deliveryRouteId");
  static final QueryField DELIVERYROUTEPOINTSTATEID = QueryField(fieldName: "deliveryRoutePointStateId");
  static var schema = Model.defineSchema(define: (ModelSchemaDefinition modelSchemaDefinition) {
    modelSchemaDefinition.name = "AddMoreEvidence";
    modelSchemaDefinition.pluralName = "AddMoreEvidences";

    modelSchemaDefinition.authRules = [
      AuthRule(
        authStrategy: AuthStrategy.PRIVATE,
        operations: [
          ModelOperation.CREATE,
          ModelOperation.UPDATE,
          ModelOperation.DELETE,
          ModelOperation.READ
        ])
    ];

    modelSchemaDefinition.addField(ModelFieldDefinition.id());

    modelSchemaDefinition.addField(ModelFieldDefinition.field(
      key: AddMoreEvidence.DELIVERYROUTEPOINTID,
      isRequired: true,
      ofType: ModelFieldType(ModelFieldTypeEnum.int)
    ));

    modelSchemaDefinition.addField(ModelFieldDefinition.field(
      key: AddMoreEvidence.EVIDENCES,
      isRequired: false,
      isArray: true,
      ofType: ModelFieldType(ModelFieldTypeEnum.collection, ofModelName: describeEnum(ModelFieldTypeEnum.string))
    ));

    modelSchemaDefinition.addField(ModelFieldDefinition.field(
      key: AddMoreEvidence.DELIVERYROUTEID,
      isRequired: true,
      ofType: ModelFieldType(ModelFieldTypeEnum.int)
    ));

    modelSchemaDefinition.addField(ModelFieldDefinition.field(
      key: AddMoreEvidence.DELIVERYROUTEPOINTSTATEID,
      isRequired: true,
      ofType: ModelFieldType(ModelFieldTypeEnum.int)
    ));

    modelSchemaDefinition.addField(ModelFieldDefinition.nonQueryField(
      fieldName: 'createdAt',
      isRequired: false,
      isReadOnly: true,
      ofType: ModelFieldType(ModelFieldTypeEnum.dateTime)
    ));

    modelSchemaDefinition.addField(ModelFieldDefinition.nonQueryField(
      fieldName: 'updatedAt',
      isRequired: false,
      isReadOnly: true,
      ofType: ModelFieldType(ModelFieldTypeEnum.dateTime)
    ));
  });
}

class _AddMoreEvidenceModelType extends ModelType<AddMoreEvidence> {
  const _AddMoreEvidenceModelType();

  @override
  AddMoreEvidence fromJson(Map<String, dynamic> jsonData) {
    return AddMoreEvidence.fromJson(jsonData);
  }
}
> flutter doctor -v
Doctor summary (to see all details, run flutter doctor -v):
[✓] Flutter (Channel stable, 2.10.4, on Ubuntu 22.04.1 LTS 5.15.0-47-generic, locale es_CO.UTF-8)
[✓] Android toolchain - develop for Android devices (Android SDK version 33.0.0)
[✓] Chrome - develop for the web
[✓] Android Studio (version 2021.2)
[✓] VS Code (version 1.70.2)
[✓] Connected device (2 available)
[✓] HTTP Host Availability

• No issues found!

Steps to reproduce the error:

  1. Run the app in dev release mode.
  2. Turn off the WiFi and Mobile connection internet
  3. Save some model using Amplify.DataStore.save(instanceModel).
  4. Close app (kill background)
  5. Open app and run the Amplify.DataStore.start() method

The behavior is that the app freezes and after in FirebaseCrashlytics I can view this error: cause=DataStoreException{message=Timed out acquiring orchestrator lock., cause=null, recoverySuggestion=Retry your request.}, recoverySuggestion=Retry.}

M7MMAD-OMAR commented 1 year ago

change auth table from schema.graphql to this

type User @model @auth(rules: [{allow: public}]) { // your table code }

tylerjroach commented 11 months ago

There are a number of transition threading fixes that have been released since this ticket was last commented on.

I'm going to go ahead and close this for now, but please let us know if issues persist with the last versions of Amplify Android v2 and we will continue researching.

github-actions[bot] commented 11 months ago

⚠️COMMENT VISIBILITY WARNING⚠️

Comments on closed issues are hard for our team to see. If you need more assistance, please either tag a team member or open a new issue that references this one. If you wish to keep having a conversation with other community members under this issue feel free to do so.