Android에서 Realm에 모델 매개변수를 추가할 때 이전 모든 버전에서 매개변수가 있는지 고려해야 함

SNS pirika의 안드로이드 앱과 관련해서는 단계적으로 v5가 공개됐다.4.13, v5.4.14 버전에서 부팅 충돌 문제가 발생했습니다.v5.4.13에서 Realm 버전 업그레이드와 Realm 작업 주변의 역할을 분리했는데 그 중에서 이전 처리가 완비되지 않은 것이 원인이다.본문은 그 경과를 공유할 것이다.
배경.
SNS pirika에는 이벤트 기능이 있지만 이벤트 일람을 캐시하기 위해 Realm 프로그램 라이브러리를 사용합니다.v5.4.12까지 Realm 버전은 v7이다.0.8.그래서 리얼엠을0.0 이상으로 업데이트하기 위해서는 응용 프로그램의 수정 처리가 필요합니다.Realm v100.0 부터 데이터를 쓰기 시작하려면 UI 스레드 외부에서 시작해야 합니다.
또 당시 리얼엠을 조작한 부분 처리가 뷰 조작과 밀접하게 결합한 문제가 있어 유지보수가 어려울 수도 있다.이에 따라 리얼m 버전이 업그레이드되면서 리얼m 작업의 주변과 이를 제외한 임무도 분리됐다.
v5.4.12 → v5.4.13
컨텐트 수정
다음 그림에 따라 수정되었습니다.변경점은 다음과 같은 세 가지가 있습니다.
  • Realm 작업용 모듈만 터치(아래 그림은 EventeDatastore)
  • 영구 데이터 모델은 1이다.의 모듈 내 처리, 외부에서 상업 논리를 사용하는 데이터 모델
  • 예를 들어 이벤트 목록의 지속화 데이터 모델인 이벤트데이터(이하 구 이벤트데이터라고 함)를 지속성 이벤트데이터와 상업 논리에 사용되는 이벤트데이터로 분할한다.1. 내부에서만 EventDataPersist,1을 사용합니다.의 인터페이스에서 EventeData
  • 허용
  • Realm v10.대응 x: 쓰기 작업은 UI 스레드가 아니라 Coroutine에서 발표한 배경 스레드에서 진행됩니다

  • Realmv10 이상의 쓰기 예제
    + CoroutineScope(Dispatchers.Main).launch {
        realm.executeTransaction {
            for( event in eventDataList){
               realm.copyToRealmOrUpdate(event)
            }
        }
    + }
    
    동작 확인
    응용 프로그램의 동작에 문제가 있는지 확인하기 위해 다음과 같은 관점에서 동작 평가를 실시했다.
  • 지속적인 데이터의 쓰기/읽기는 v5입니다.4.12 동일
  • EventeDataPersist를 읽으면 View가 업데이트됩니다
  • .
    어떤 관점이든 문제가 없기 때문이다.4.13 발매에 들어갔다.변경 규모가 수백 줄에 달해 20% 단계부터 공개한다.
    새로 발생한 문제
    공개 2일 후 몇 개의 터미널이 작동된 후 붕괴되었다.잘못된 세부 정보를 보고
    io.realm.exceptions.RealmMigrationNeededException
    ...
    Migration is required due to the following errors: - Property 'EventPersistentModel.theParam' has been added.
    
    theParam의 정의가 구 이벤트데이터에 없기 때문에 붕괴가 발생했습니다.
    리얼엠은 대응하는 원코드를 업데이트해 몇 달 전에 준비했다.하지만 그곳에서 메르지까지 이어지는 동안 theParam 매개 변수는 이벤트데이터에 별도의 PR에 추가됐다.이 PR 검토에 더해 이벤트데이터, 이벤트퍼시스턴모델에도 매개 변수가 함께 추가됐지만 마이그레이션 처리에서 해당 매개 변수가 누락됐다.
    v5.4.13 → v5.4.14
    필요한 수정 사항
    이전 EventData에 theParam을 추가하는 것은 v5입니다.4.10에 실시한다.그래서 이번에 붕괴된 것은 v5였다.4.9 이하의 응용 프로그램이나 v5.4.10을 초과하더라도 이벤트데이터는 업데이트되지 않을 것으로 추정하고 있습니다.실제로4.9→v5.4.10이면 문제 없이 업데이트됩니다.
    따라서 이전 처리에 다음과 같은 내용을 추가했다.
    +    realmSchema.get("EventData")
    +        ?.addField(
    +            "theParam",
    +            Int::class.javaObjectType,
    +            FieldAttribute.REQUIRED)
        realmSchema.rename(
            "EventData", "EventPersistentModel")
    
    따라서 EventData 모드에 theParam이 없으면 theParam이 추가됩니다.
    동작 확인
    다음과 같은 관점에서 평가를 진행하였다.어떤 동작이든 문제없다.
  • ✅ 프로젝트 1.v5.4. x-5.4.9 이전 프로그램에서 시작하고 이벤트 목록을 열면 v5.4.14에서 업데이트 및 시작 가능
  • ✅ 프로젝트 2.v5.4. x-5.4.9 이전 프로그램에서 시작하고 이벤트 일람을 연 후 v5를 한 번 엽니다.4.13 업데이트.작동 후 충돌 확인, v5.4.14에서 업데이트 및 시작 가능
  • ✅ 항목v5.4. x-5.4.9 이전 프로그램에서 시작하고 이벤트 목록을 열면 v5.4.10-v.4.2 업데이트.프로그램이 시작된 후 이벤트 일람을 한 번도 열지 않았습니다. v5.4.14에서 업데이트 및 시작 가능
  • 위와 같은 움직임이 확인돼 그대로 발표됐다.하지만 이번에는 정성껏 제작해 10% 단계부터 공개한다.
    우리는 Migration의 문제가 이미 해결되었다고 생각한다.
    새로 발생한 문제
    v5.4.14 업데이트된 사용자 중 시작 충돌이 발생했습니다. 이것은 이벤트데이터에 theParam이 있음을 나타냅니다.상기 항목 3.의 모드로 과거 활동 일람을 볼 때 v5.4.10-5.4.12 시작 후 이벤트 목록을 볼 때 이벤트 데이터는 the Param을 추가합니다.그래서 이번 붕괴가 일어났다.
    Fatal Exception: java.lang.IllegalArgumentException
    Field already exists in 'EventData': theParam
    
    v5.4.14 → v5.4.15
    대응 내용
    이전 처리에서 더 팔람이 없을 때만 더 팔람을 추가하는 것을 수정했다.
    -    realmSchema.get("EventData")
    -    ?.addField(
    +    val eventData = realmSchema.get("EventData")
    +    if(eventData?.hasField("theParam") != true){
    +        eventData?.addField(
                 "theParam",
                 Int::class.javaObjectType,
                 FieldAttribute.REQUIRED)
    +    }
         realmSchema.rename(
             "EventData", "EventPersistentModel")
    
    동작 확인
    v5.4.14의 동작 확인 외에 v5도 한 번 확인해야 한다.4.10-5.4.12는 이벤트 일람을 지난 몇 달 동안 올린 뒤 5.4.15로 업데이트한다는 관점을 추가해 업데이트했다.일련의 동작에 문제가 없음을 확인한 후, v5.단계별로 4.15를 공개했다.v5.4.15 부팅 충돌이 발생하지 않으며 어플리케이션을 정상적으로 사용할 수 있습니다.
    회고: 두 번의 업데이트를 성공적으로 진행할 수 없는 이유
    몇 가지 이유가 있는데, 주로 다음과 같다.
  • Realm의 변경 내용은 리뷰에 포함되지 않았습니다. 구조 변경과 Breaking Chage가 대응하기 때문에 리뷰→다른 Realm 경험자가 있기 때문에 검사할 여지가 있습니다
  • Realm의 이전에 모델이 필요한지 이해할 수 없음: Realm의 이전에 대해 v5.4.10에는 문제가 없기 때문에 theParam의 마이그레이션 대응이 필요하지 않다고 판단했다.그래서4.13 가동 붕괴를 초래했다.
  • v5.4.12 이전에는 d e l eteRealmIf Migration Needd를 사용했으므로 마이그레이션이 필요하지만 해당 마이그레이션 처리 없이 Realm 내의 데이터를 지웁니다.그래서 이번 문제는 발생하지 않았다.v5.4.13에서는 지금까지의 영구화 데이터를 최대한 활용하기 위해 삭제 형태로 대응했으나 이번 문제가 발생한 원인이 됐다.
  • 평가 관점에서 볼 때 EventeData.망라 the Param의 유/무: 망라가 여기 있으면, v5.4.14 판정 발표 시 가동 붕괴에 주의해야 한다
  • 위에서 말한 바와 같이 다음과 같은 대책을 열거할 수 있다.
  • 이번처럼 홍보 규모가 클 때 십자 점검에 가입
  • OS의 API 변경 대응, 라이브러리의 Breaking Change 대응, 사양 변경에 따른 기능 추가, 변경의 영향이 크기 때문에 반드시 실시해야 한다
  • 평가 관점에 대해 과거 버전의 망라/지구화 데이터 모델이 없는 필드에 대해 모든 관점을 검사할 수 있도록 평가 항목을 작성한다
  • 이상, 시청해 주셔서 감사합니다!

    좋은 웹페이지 즐겨찾기