SlideShare una empresa de Scribd logo
1 de 107
Descargar para leer sin conexión
MobileNativeFoundation/Store
meet
Store 5
mattramotar@androidDev.social
friendlyMike@androidDev.Social
Droidcon SF 2023
What is Store?
Store is a Java library for effortless, reactive data loading.
Guarantee things [you don’t want to think about] are done in the same way
What is Store?
Contracts + RELIABILITY
Guarantee things are done in the same way
What is Store?
Store
A brief history
2017 2019 2021 2022 2023
Store A brief history
2017
2019
1.0 Released Jan 17th, 2017 by NY Times
2017
2019
Why did we need Store?
We wanted to do complicated thing once
Store Version 1.0 Api
2017
2019
Store [was] a Java library for effortless, reactive data loading built with RxJava
Store<Article> Store = ParsingStoreBuilder.<BufferedSource, String>builder()
.fetcher(this::ResponseAsSource)
.persister(SourcePersisterFactory.create(context.getFilesDir())
.parser(GsonParserFactory.createSourceParser(gson, Article.class))
.open();
Barcode barcode = new Barcode("Article", "42");
store.get(barcode).subscribe(onNext, onError, onComplete)
2017
2019
Fresh == skip memory/persister go directly to fetcher
store.fresh(param).subscribe(onNext, onError, onComplete)
Fresh Skip Caches
Store Why You Need User Research
2.0 Released 1 month later (oops!)
2017
2019
3.0 Api Rxjava2
RxSingle instead of Observable
Store<Article> Store = ParsingStoreBuilder.<BufferedSource,ArticleParam, String>builder()
.fetcher(this::ResponseAsSource) //responseBody.source()
.persister(SourcePersisterFactory.create(context.getFilesDir())
.parser(GsonParserFactory.createSourceParser(gson, Article.class))
.open();
ArticleParam param = new ArticleParam("42");
store.get(param).subscribe(onNext, onError)
2017
2019
Store
Coroutines have hit stable
2017
2019
2021
Fast forward to 2019
Bye bye RxJava Hello Kotlin
2017
2019
2021
Store4
Fast forward to 2019
Hello Kotlin
2017
2019
2021
Store4
StoreBuilder.from { api.fetchSubreddit(it, "10")}
.sourceOfTruth(
reader = db.postDao()::loadPosts,
writer = db.postDao()::insertPosts,
delete = db.postDao()::clearFeed)
.cachePolicy(MemoryPolicy)
.build()
Api
Streaming as first class citizen
2017
2019
2021
fun stream(request: StoreRequest<Key>): Flow<StoreResponse>Output>>
lifecycleScope.launchWhenStarted {
store.stream(StoreRequest.cached(3, refresh = false))
.collect{ }
store.stream(StoreRequest.get(3)) .collect{ storeResponse -> }
Store4 Api
Loading|Content|Error Return Types
2017
2019
2021
Store 4
store.stream(StoreRequest.cached(key = key, refresh=true)).collect { response ->
when(response) {
is StoreResponse.Loading -> showLoadingSpinner()
is StoreResponse.Data -> {
if (response.origin == ResponseOrigin.Fetcher) hideLoadingSpinner()
updateUI(response.value)
}
is StoreResponse.Error -> {
if (response.origin == ResponseOrigin.Fetcher) hideLoadingSpinner()
showError(response.error)
}}}}
LCE
Using Store 4
Examples are from Firefly for Mastodon
https://github.com/digitalbuddha/Firefly
2017
2019
2021
You create a Store using a builder. The only requirement is to include a Fetcher which is just a typealias to a
function that returns a Flow<FetcherResult<ReturnType>>.
//build it
val store = StoreBuilder.from(
Fetcher.of { key: Unit ->
userApi.noti
fi
cations(
authHeader = " Bearer ${oauthRepository.getCurrent()}",
offset = null)
}).build()
//use it
store.stream(StoreRequest.cached(Unit, refresh = true)).map { it.dataOrNull()
}
.collect{response-> }
Fetcher as a Function
2017
2019
2021
How we get data
2017
2019
2021
Do the hard thing once
How to work with local persistence
Source of Truth
suspend fun fetcher(key:String): Token = api.createAccessToken(key)
fun sourceOfTruth = SourceOfTruth.of<String, Token, String>(
reader = {dataStore.data.map { it.currentUser?.accessToken }},
writer = { _, token -> dataStore.updateData {
it.user.copy(accessToken = token.accessToken)
}})
private val userTokenStore: Store<String, String> =
StoreBuilder.from(
fetcher = Fetcher.of { key: String -> fetcher(key) },
sourceOfTruth = sourceOfTruth
).build()
2017
2019
2021
2017
2019
2021
Store Data Flow
Fast forward to 2022
Where we were 365 days ago
2021
2022
2023
Store 4 is stable
Less than a dozen open bugs
2021
2022
2023
API was perfect
As long as you only asked me
2021
2022
2023
We had LOTS of feature requests
2021
2022
2023
That I was ignoring
2021
2022
2023
Write Support (CRUD)
2021
2022
2023
Conflict Resolution
2021
2022
2023
Fallback Mechanisms
2021
2022
2023
Support for Collections
2021
2022
2023
Store 5
Introducing
Store now with batteries included
Mission-Critical
Server-Driven Architecture
Sync
Collaboration
Upload + Download
Data Protection
Offline Access
Campaigns
Server-driven UI
Don’t worry
Store 5 is a superset of Store4
Which targets JVM/iOS/Web
How we got here…
Try 1…Adding Write Support
Rewrite what you don’t understand
Mike: What is the bene
fi
t of starting over?
Matt: Hmm
Mike: Is it easier to add old to new or new to old?
Some time later… (half hour)
Matt: safeguards will be easier to add to new
Matt: because I don’t understand old
Mike: SGTM as long as all tests are migrated, I also
don’t understand old
Matt: Sure how hard can it be?
Many days later:
Mike: ….
Matt: …
More time passes
Mike: My spider sense is tingling, I found more
gaps in new
Mike: let’s sit together and go through Store4
code
Try 2…Extending the old
Rather than boiling the ocean
Few weeks later…
Matt:Just finished last test cases everything passes
Mike: Everything?
Matt: Yup in iOS, android, JVM and JS, I took all the
work https://github.com/aclassen did and got it to pass
tests
What’sinStore5
Mutations
Con
fl
ict Resolution
Fallback Mechanisms
List Decomposition
Cache Delegation
Validation
Concepts
meet
Trails
An offline-first companion
Trails
User Story - Hiking
without Internet
Trails Architecture TLDR
Data Pulled & Pushed
Source of Truth to
Repository
Data Flow
Can’t do with Store 4
Source of Truth to
Repository
Data Flow
interface Updater<Key, Output, Response> {
suspend fun post(key: Key, value: Output):
UpdaterResult
val onCompletion:
OnUpdaterCompletion<Response>?}
Store 5 New Mutation Api
Creating an Updater (like a fetcher)
UpdatingRemoteData
sample
val updater = Updater.by(
post = { _, hike ->
try {
val latest = api.updateHike(hike)
UpdaterResult.Success.Typed(latest)
} catch (error: Throwable) {
UpdaterResult.Error.Exception(error)
}})
Store 5 Updater Factory
val mutableStore = store.asMutableStore(
updater = updater,
bookkeeper = bookkeeper)
Store 5 Mutable Store Builder
class RealHikeManager @Inject constructor(
private val mutableStore: MutableStore<Int, Hike>,
private val location:locationRepository,
private val map:mapRepository
): HikeManager {
private suspend fun track() {
combine(location.current(),
map.current()) { location, map ->
val request =
createStoreWriteRequest(location, map)
val response = mutableStore.write(request)
handleResponse(response)
}}}
Store 5 Usage of MutableStore
class RealHikeManager @Inject constructor(
private val mutableStore: MutableStore<Int, Hike>,
private val location:locationRepository,
private val map:mapRepository
): HikeManager {
private suspend fun track() {
combine(location.current(),
map.current()) { location, map ->
val request =
createStoreWriteRequest(location, map)
val response = mutableStore.write(request)
handleResponse(response)
}}}
Store 5 Usage of MutableStore
What happens if write fails
or a competing write?
Con
fl
ict Resolution
Store 5 Concepts
https://developer.android.com/topic/architecture/data-layer/o
ffl
ine-
fi
rst#last-write
Non Happy Path == Hard
How Does Store 5 Resolves Con
fl
icts?
Implementing Principles
How Store 5 Resolves Conflicts
We Don’t You Do!
With Delegation
What we need from you
A Bookkeeper (delegate)
Bookkeeper?
Tracks when local changes fail to sync with
network
Store 5 Bookkeeper Api
interface Bookkeeper<Key : Any> {
suspend fun getLastFailedSync(key: Key): Long?
suspend fun setLastFailedSync(key: Key, timestamp: Long): Boolean
suspend fun clear(key: Key): Boolean
suspend fun clearAll(): Boolean}
MutableStore
+ Bookkeeper
Before completing a read request,
MutableStore asks Bookkeeper
whether any conflicts might exist
Store 5 - Any Conflicts? RealMutableStore
private suspend fun con
fl
ictsMightExist(key: Key): Boolean {
val lastFailedSync = bookkeeper?.getLastFailedSync(key)
return lastFailedSync != null || writeRequestsQueueIsEmpty(key).not()
}
MutableStore
+ Bookkeeper
And if conflicts might exist,
MutableStore tries to eagerly resolve them
What we think you should do
Resolve conflicts on remote
On each write request
1. Init thread safety (key-scoped)
2. Add request to stack (key-scoped)
3. Write to memory cache + SOT!!!
4. Try to update network (posting latest)
Mutations In the Weeds
On each write request
1. Init thread safety (key-scoped)
2. Add request to stack (key-scoped)
3. Write to memory cache + SOT!!!
4. Try to update network (posting latest)
In the Weeds
Mutations
On each write request
1. Init thread safety (key-scoped)
2. Add request to stack (key-scoped)
3. Write to memory cache + SOT!!!
4. Try to update network (posting latest)
In the Weeds
Mutations
On each write request
1. Init thread safety (key-scoped)
2. Add request to stack (key-scoped)
3. Write to memory cache + SOT!!!
4. Try to update network (posting latest)
In the Weeds
Mutations
When network response
1. Success
1. Reset stack
2. Reset bookkeeper
2. Failure
1. Log with bookkeeper
Try to update network
When network response
1. Success
1. Reset stack
2. Reset bookkeeper
2. Failure
1. Log with bookkeeper
Try to update network
When network response
1. Success
1. Reset stack
2. Reset bookkeeper
2. Failure
1. Log with bookkeeper
Try to update network
When network response
1. Success
1. Reset stack
2. Reset bookkeeper
2. Failure
1. Log with bookkeeper
Try to update network
When network response
1. Success
1. Reset stack
2. Reset bookkeeper
2. Failure
1. Log with bookkeeper
Try to update network
Fallback Mechanisms
Always have a backup plan!
Fallback Mechanisms
Store 5 Fetcher Api
fun <Key : Any, Network : Any> of(
name: String? = null,
fetch: suspend (key: Key) -> Network
): Fetcher<Key, Network> = ofFlow(name, fetch.asFlow())
fun <Key : Any, Network : Any> of(
name: String? = null,
fallback: Fetcher<Key, Network>,
fetch: suspend (key: Key) -> Network
): Fetcher<Key, Network> =
ofFlowWithFallback(name, fallback, fetch.asFlow())
Store 5 Fetcher Api with fallback
User Story - A/B Testing
data class FeatureFlag(
val key: String,
val name: String,
val description: String,
val kind: Kind,
val version: Int,
val creationDate: Long,
) : Identi
fi
able<String> {
enum class Kind { Boolean, Multivariate}}
Trails Feature Flag Model
Trails Feature Flag Status Model
sealed class FeatureFlagStatus: Identi
fi
able<String> {
data class Multivariate(
val key: String,
val value: FeatureFlagVariation,
val lastRequested: Long,
val links: Links)}
Trails Feature Flag
Architecture
Fallback Mechanisms
sample
Network Feature Flag Status Fetcher
With Fallback
val networkFetcher = Fetcher.ofWithFallback(
name = “networkFetcher”,
fallback = hardcodedFetcher
) { key ->
when (key) {
is Collection -> fetchFeatureFlagStatuses(key.userId)
is Single -> fetchFeatureFlagStatus(key.userId, key.
fl
agId)}}
Hardcoded Feature Flag Status Fetcher
val hardcodedFetcher = Fetcher.of(
name = “hardcodedFetcher”
) { key ->
when (key) {
is Collection -> loadFeatureFlagStatuses(key.userId)
is Single -> loadFeatureFlagStatus(key.userId, key.
fl
agId)}}
Build Store as normal
val store = StoreBuilder.from(
fetcher = networkFetcher,
sourceOfTruth = sourceOfTruth,
memoryCache = multiCache
).toMutableStoreBuilder<FeatureFlagStatusData,
FeatureFlagStatusData>().build(
updater = updater,
bookkeeper = bookkeeper)
Concepts
List Decomposition
Cache Delegation
WorkingWithCollections
sample
Just works
Store Loves KMP
We target Android/
Desktop/iOS/JS
Store 5 Beta is out now
github.com/mobilenativefoundation/store

Más contenido relacionado

Similar a meetstore5.pdf

Scale Your Data Tier With Windows Server App Fabric
Scale Your Data Tier With Windows Server App FabricScale Your Data Tier With Windows Server App Fabric
Scale Your Data Tier With Windows Server App FabricChris Dufour
 
Max Koretskyi "Why are Angular and React so fast?"
Max Koretskyi "Why are Angular and React so fast?"Max Koretskyi "Why are Angular and React so fast?"
Max Koretskyi "Why are Angular and React so fast?"Fwdays
 
Memcached Presentation @757rb
Memcached Presentation @757rbMemcached Presentation @757rb
Memcached Presentation @757rbKen Collins
 
Programmers, communicate your intentions
Programmers, communicate your intentionsProgrammers, communicate your intentions
Programmers, communicate your intentionsYael Zaritsky Perez
 
Reactive programming with RxJava
Reactive programming with RxJavaReactive programming with RxJava
Reactive programming with RxJavaJobaer Chowdhury
 
Intro to Asynchronous Javascript
Intro to Asynchronous JavascriptIntro to Asynchronous Javascript
Intro to Asynchronous JavascriptGarrett Welson
 
Principles of the Play framework
Principles of the Play frameworkPrinciples of the Play framework
Principles of the Play frameworkBernhard Huemer
 
Kickin' Ass with Cache-Fu (without notes)
Kickin' Ass with Cache-Fu (without notes)Kickin' Ass with Cache-Fu (without notes)
Kickin' Ass with Cache-Fu (without notes)err
 
Node.js - iJS 2019
Node.js - iJS 2019Node.js - iJS 2019
Node.js - iJS 2019NilsMehlhorn
 
Intro to React - Featuring Modern JavaScript
Intro to React - Featuring Modern JavaScriptIntro to React - Featuring Modern JavaScript
Intro to React - Featuring Modern JavaScriptjasonsich
 
The uniform interface is 42
The uniform interface is 42The uniform interface is 42
The uniform interface is 42Yevhen Bobrov
 
3 Mobile App Dev Problems - Monospace
3 Mobile App Dev Problems - Monospace3 Mobile App Dev Problems - Monospace
3 Mobile App Dev Problems - MonospaceFrank Krueger
 
Matthew Vignau: Memory Management in SharePoint 2007 Development
Matthew Vignau: Memory Management in SharePoint 2007 DevelopmentMatthew Vignau: Memory Management in SharePoint 2007 Development
Matthew Vignau: Memory Management in SharePoint 2007 DevelopmentSharePoint Saturday NY
 

Similar a meetstore5.pdf (20)

Scale Your Data Tier With Windows Server App Fabric
Scale Your Data Tier With Windows Server App FabricScale Your Data Tier With Windows Server App Fabric
Scale Your Data Tier With Windows Server App Fabric
 
Java Performance Tuning
Java Performance TuningJava Performance Tuning
Java Performance Tuning
 
Max Koretskyi "Why are Angular and React so fast?"
Max Koretskyi "Why are Angular and React so fast?"Max Koretskyi "Why are Angular and React so fast?"
Max Koretskyi "Why are Angular and React so fast?"
 
Memcached Presentation @757rb
Memcached Presentation @757rbMemcached Presentation @757rb
Memcached Presentation @757rb
 
Ejb examples
Ejb examplesEjb examples
Ejb examples
 
Programmers, communicate your intentions
Programmers, communicate your intentionsProgrammers, communicate your intentions
Programmers, communicate your intentions
 
Reactive programming with RxJava
Reactive programming with RxJavaReactive programming with RxJava
Reactive programming with RxJava
 
Intro to Asynchronous Javascript
Intro to Asynchronous JavascriptIntro to Asynchronous Javascript
Intro to Asynchronous Javascript
 
Principles of the Play framework
Principles of the Play frameworkPrinciples of the Play framework
Principles of the Play framework
 
RxSwift to Combine
RxSwift to CombineRxSwift to Combine
RxSwift to Combine
 
Kickin' Ass with Cache-Fu (without notes)
Kickin' Ass with Cache-Fu (without notes)Kickin' Ass with Cache-Fu (without notes)
Kickin' Ass with Cache-Fu (without notes)
 
Node.js - iJS 2019
Node.js - iJS 2019Node.js - iJS 2019
Node.js - iJS 2019
 
Intro to React - Featuring Modern JavaScript
Intro to React - Featuring Modern JavaScriptIntro to React - Featuring Modern JavaScript
Intro to React - Featuring Modern JavaScript
 
The uniform interface is 42
The uniform interface is 42The uniform interface is 42
The uniform interface is 42
 
Lambdas puzzler - Peter Lawrey
Lambdas puzzler - Peter LawreyLambdas puzzler - Peter Lawrey
Lambdas puzzler - Peter Lawrey
 
3 Mobile App Dev Problems - Monospace
3 Mobile App Dev Problems - Monospace3 Mobile App Dev Problems - Monospace
3 Mobile App Dev Problems - Monospace
 
Matthew Vignau: Memory Management in SharePoint 2007 Development
Matthew Vignau: Memory Management in SharePoint 2007 DevelopmentMatthew Vignau: Memory Management in SharePoint 2007 Development
Matthew Vignau: Memory Management in SharePoint 2007 Development
 
Solving the n + 1 query problem
Solving the n + 1 query problemSolving the n + 1 query problem
Solving the n + 1 query problem
 
Java
JavaJava
Java
 
Devf (Shoe Lovers)
Devf (Shoe Lovers)Devf (Shoe Lovers)
Devf (Shoe Lovers)
 

Más de Mike Nakhimovich

Dispatching Reactive State
Dispatching Reactive StateDispatching Reactive State
Dispatching Reactive StateMike Nakhimovich
 
Intro to GraphQL on Android with Apollo DroidconNYC 2017
Intro to GraphQL on Android with Apollo DroidconNYC 2017Intro to GraphQL on Android with Apollo DroidconNYC 2017
Intro to GraphQL on Android with Apollo DroidconNYC 2017Mike Nakhimovich
 
Data Loading Made Easy with Mike Nakhimovich DroidCon Italy 2017
Data Loading Made Easy with Mike Nakhimovich DroidCon Italy 2017Data Loading Made Easy with Mike Nakhimovich DroidCon Italy 2017
Data Loading Made Easy with Mike Nakhimovich DroidCon Italy 2017Mike Nakhimovich
 
Advanced Dagger talk from 360andev
Advanced Dagger talk from 360andevAdvanced Dagger talk from 360andev
Advanced Dagger talk from 360andevMike Nakhimovich
 
Sword fighting with Dagger GDG-NYC Jan 2016
 Sword fighting with Dagger GDG-NYC Jan 2016 Sword fighting with Dagger GDG-NYC Jan 2016
Sword fighting with Dagger GDG-NYC Jan 2016Mike Nakhimovich
 
Intro to Functional Programming with RxJava
Intro to Functional Programming with RxJavaIntro to Functional Programming with RxJava
Intro to Functional Programming with RxJavaMike Nakhimovich
 

Más de Mike Nakhimovich (6)

Dispatching Reactive State
Dispatching Reactive StateDispatching Reactive State
Dispatching Reactive State
 
Intro to GraphQL on Android with Apollo DroidconNYC 2017
Intro to GraphQL on Android with Apollo DroidconNYC 2017Intro to GraphQL on Android with Apollo DroidconNYC 2017
Intro to GraphQL on Android with Apollo DroidconNYC 2017
 
Data Loading Made Easy with Mike Nakhimovich DroidCon Italy 2017
Data Loading Made Easy with Mike Nakhimovich DroidCon Italy 2017Data Loading Made Easy with Mike Nakhimovich DroidCon Italy 2017
Data Loading Made Easy with Mike Nakhimovich DroidCon Italy 2017
 
Advanced Dagger talk from 360andev
Advanced Dagger talk from 360andevAdvanced Dagger talk from 360andev
Advanced Dagger talk from 360andev
 
Sword fighting with Dagger GDG-NYC Jan 2016
 Sword fighting with Dagger GDG-NYC Jan 2016 Sword fighting with Dagger GDG-NYC Jan 2016
Sword fighting with Dagger GDG-NYC Jan 2016
 
Intro to Functional Programming with RxJava
Intro to Functional Programming with RxJavaIntro to Functional Programming with RxJava
Intro to Functional Programming with RxJava
 

Último

Structural Analysis and Design of Foundations: A Comprehensive Handbook for S...
Structural Analysis and Design of Foundations: A Comprehensive Handbook for S...Structural Analysis and Design of Foundations: A Comprehensive Handbook for S...
Structural Analysis and Design of Foundations: A Comprehensive Handbook for S...Dr.Costas Sachpazis
 
(SHREYA) Chakan Call Girls Just Call 7001035870 [ Cash on Delivery ] Pune Esc...
(SHREYA) Chakan Call Girls Just Call 7001035870 [ Cash on Delivery ] Pune Esc...(SHREYA) Chakan Call Girls Just Call 7001035870 [ Cash on Delivery ] Pune Esc...
(SHREYA) Chakan Call Girls Just Call 7001035870 [ Cash on Delivery ] Pune Esc...ranjana rawat
 
MANUFACTURING PROCESS-II UNIT-1 THEORY OF METAL CUTTING
MANUFACTURING PROCESS-II UNIT-1 THEORY OF METAL CUTTINGMANUFACTURING PROCESS-II UNIT-1 THEORY OF METAL CUTTING
MANUFACTURING PROCESS-II UNIT-1 THEORY OF METAL CUTTINGSIVASHANKAR N
 
High Profile Call Girls Nagpur Isha Call 7001035870 Meet With Nagpur Escorts
High Profile Call Girls Nagpur Isha Call 7001035870 Meet With Nagpur EscortsHigh Profile Call Girls Nagpur Isha Call 7001035870 Meet With Nagpur Escorts
High Profile Call Girls Nagpur Isha Call 7001035870 Meet With Nagpur Escortsranjana rawat
 
High Profile Call Girls Nagpur Meera Call 7001035870 Meet With Nagpur Escorts
High Profile Call Girls Nagpur Meera Call 7001035870 Meet With Nagpur EscortsHigh Profile Call Girls Nagpur Meera Call 7001035870 Meet With Nagpur Escorts
High Profile Call Girls Nagpur Meera Call 7001035870 Meet With Nagpur EscortsCall Girls in Nagpur High Profile
 
(ANJALI) Dange Chowk Call Girls Just Call 7001035870 [ Cash on Delivery ] Pun...
(ANJALI) Dange Chowk Call Girls Just Call 7001035870 [ Cash on Delivery ] Pun...(ANJALI) Dange Chowk Call Girls Just Call 7001035870 [ Cash on Delivery ] Pun...
(ANJALI) Dange Chowk Call Girls Just Call 7001035870 [ Cash on Delivery ] Pun...ranjana rawat
 
(PRIYA) Rajgurunagar Call Girls Just Call 7001035870 [ Cash on Delivery ] Pun...
(PRIYA) Rajgurunagar Call Girls Just Call 7001035870 [ Cash on Delivery ] Pun...(PRIYA) Rajgurunagar Call Girls Just Call 7001035870 [ Cash on Delivery ] Pun...
(PRIYA) Rajgurunagar Call Girls Just Call 7001035870 [ Cash on Delivery ] Pun...ranjana rawat
 
Russian Call Girls in Nagpur Grishma Call 7001035870 Meet With Nagpur Escorts
Russian Call Girls in Nagpur Grishma Call 7001035870 Meet With Nagpur EscortsRussian Call Girls in Nagpur Grishma Call 7001035870 Meet With Nagpur Escorts
Russian Call Girls in Nagpur Grishma Call 7001035870 Meet With Nagpur EscortsCall Girls in Nagpur High Profile
 
CCS335 _ Neural Networks and Deep Learning Laboratory_Lab Complete Record
CCS335 _ Neural Networks and Deep Learning Laboratory_Lab Complete RecordCCS335 _ Neural Networks and Deep Learning Laboratory_Lab Complete Record
CCS335 _ Neural Networks and Deep Learning Laboratory_Lab Complete RecordAsst.prof M.Gokilavani
 
Extrusion Processes and Their Limitations
Extrusion Processes and Their LimitationsExtrusion Processes and Their Limitations
Extrusion Processes and Their Limitations120cr0395
 
Introduction and different types of Ethernet.pptx
Introduction and different types of Ethernet.pptxIntroduction and different types of Ethernet.pptx
Introduction and different types of Ethernet.pptxupamatechverse
 
Top Rated Pune Call Girls Budhwar Peth ⟟ 6297143586 ⟟ Call Me For Genuine Se...
Top Rated  Pune Call Girls Budhwar Peth ⟟ 6297143586 ⟟ Call Me For Genuine Se...Top Rated  Pune Call Girls Budhwar Peth ⟟ 6297143586 ⟟ Call Me For Genuine Se...
Top Rated Pune Call Girls Budhwar Peth ⟟ 6297143586 ⟟ Call Me For Genuine Se...Call Girls in Nagpur High Profile
 
UNIT-III FMM. DIMENSIONAL ANALYSIS
UNIT-III FMM.        DIMENSIONAL ANALYSISUNIT-III FMM.        DIMENSIONAL ANALYSIS
UNIT-III FMM. DIMENSIONAL ANALYSISrknatarajan
 
Call Girls Pimpri Chinchwad Call Me 7737669865 Budget Friendly No Advance Boo...
Call Girls Pimpri Chinchwad Call Me 7737669865 Budget Friendly No Advance Boo...Call Girls Pimpri Chinchwad Call Me 7737669865 Budget Friendly No Advance Boo...
Call Girls Pimpri Chinchwad Call Me 7737669865 Budget Friendly No Advance Boo...roncy bisnoi
 
UNIT-V FMM.HYDRAULIC TURBINE - Construction and working
UNIT-V FMM.HYDRAULIC TURBINE - Construction and workingUNIT-V FMM.HYDRAULIC TURBINE - Construction and working
UNIT-V FMM.HYDRAULIC TURBINE - Construction and workingrknatarajan
 
KubeKraft presentation @CloudNativeHooghly
KubeKraft presentation @CloudNativeHooghlyKubeKraft presentation @CloudNativeHooghly
KubeKraft presentation @CloudNativeHooghlysanyuktamishra911
 
Call for Papers - Educational Administration: Theory and Practice, E-ISSN: 21...
Call for Papers - Educational Administration: Theory and Practice, E-ISSN: 21...Call for Papers - Educational Administration: Theory and Practice, E-ISSN: 21...
Call for Papers - Educational Administration: Theory and Practice, E-ISSN: 21...Christo Ananth
 
The Most Attractive Pune Call Girls Budhwar Peth 8250192130 Will You Miss Thi...
The Most Attractive Pune Call Girls Budhwar Peth 8250192130 Will You Miss Thi...The Most Attractive Pune Call Girls Budhwar Peth 8250192130 Will You Miss Thi...
The Most Attractive Pune Call Girls Budhwar Peth 8250192130 Will You Miss Thi...ranjana rawat
 

Último (20)

Structural Analysis and Design of Foundations: A Comprehensive Handbook for S...
Structural Analysis and Design of Foundations: A Comprehensive Handbook for S...Structural Analysis and Design of Foundations: A Comprehensive Handbook for S...
Structural Analysis and Design of Foundations: A Comprehensive Handbook for S...
 
(SHREYA) Chakan Call Girls Just Call 7001035870 [ Cash on Delivery ] Pune Esc...
(SHREYA) Chakan Call Girls Just Call 7001035870 [ Cash on Delivery ] Pune Esc...(SHREYA) Chakan Call Girls Just Call 7001035870 [ Cash on Delivery ] Pune Esc...
(SHREYA) Chakan Call Girls Just Call 7001035870 [ Cash on Delivery ] Pune Esc...
 
MANUFACTURING PROCESS-II UNIT-1 THEORY OF METAL CUTTING
MANUFACTURING PROCESS-II UNIT-1 THEORY OF METAL CUTTINGMANUFACTURING PROCESS-II UNIT-1 THEORY OF METAL CUTTING
MANUFACTURING PROCESS-II UNIT-1 THEORY OF METAL CUTTING
 
High Profile Call Girls Nagpur Isha Call 7001035870 Meet With Nagpur Escorts
High Profile Call Girls Nagpur Isha Call 7001035870 Meet With Nagpur EscortsHigh Profile Call Girls Nagpur Isha Call 7001035870 Meet With Nagpur Escorts
High Profile Call Girls Nagpur Isha Call 7001035870 Meet With Nagpur Escorts
 
High Profile Call Girls Nagpur Meera Call 7001035870 Meet With Nagpur Escorts
High Profile Call Girls Nagpur Meera Call 7001035870 Meet With Nagpur EscortsHigh Profile Call Girls Nagpur Meera Call 7001035870 Meet With Nagpur Escorts
High Profile Call Girls Nagpur Meera Call 7001035870 Meet With Nagpur Escorts
 
(ANJALI) Dange Chowk Call Girls Just Call 7001035870 [ Cash on Delivery ] Pun...
(ANJALI) Dange Chowk Call Girls Just Call 7001035870 [ Cash on Delivery ] Pun...(ANJALI) Dange Chowk Call Girls Just Call 7001035870 [ Cash on Delivery ] Pun...
(ANJALI) Dange Chowk Call Girls Just Call 7001035870 [ Cash on Delivery ] Pun...
 
(PRIYA) Rajgurunagar Call Girls Just Call 7001035870 [ Cash on Delivery ] Pun...
(PRIYA) Rajgurunagar Call Girls Just Call 7001035870 [ Cash on Delivery ] Pun...(PRIYA) Rajgurunagar Call Girls Just Call 7001035870 [ Cash on Delivery ] Pun...
(PRIYA) Rajgurunagar Call Girls Just Call 7001035870 [ Cash on Delivery ] Pun...
 
Russian Call Girls in Nagpur Grishma Call 7001035870 Meet With Nagpur Escorts
Russian Call Girls in Nagpur Grishma Call 7001035870 Meet With Nagpur EscortsRussian Call Girls in Nagpur Grishma Call 7001035870 Meet With Nagpur Escorts
Russian Call Girls in Nagpur Grishma Call 7001035870 Meet With Nagpur Escorts
 
CCS335 _ Neural Networks and Deep Learning Laboratory_Lab Complete Record
CCS335 _ Neural Networks and Deep Learning Laboratory_Lab Complete RecordCCS335 _ Neural Networks and Deep Learning Laboratory_Lab Complete Record
CCS335 _ Neural Networks and Deep Learning Laboratory_Lab Complete Record
 
Extrusion Processes and Their Limitations
Extrusion Processes and Their LimitationsExtrusion Processes and Their Limitations
Extrusion Processes and Their Limitations
 
Introduction and different types of Ethernet.pptx
Introduction and different types of Ethernet.pptxIntroduction and different types of Ethernet.pptx
Introduction and different types of Ethernet.pptx
 
Top Rated Pune Call Girls Budhwar Peth ⟟ 6297143586 ⟟ Call Me For Genuine Se...
Top Rated  Pune Call Girls Budhwar Peth ⟟ 6297143586 ⟟ Call Me For Genuine Se...Top Rated  Pune Call Girls Budhwar Peth ⟟ 6297143586 ⟟ Call Me For Genuine Se...
Top Rated Pune Call Girls Budhwar Peth ⟟ 6297143586 ⟟ Call Me For Genuine Se...
 
Roadmap to Membership of RICS - Pathways and Routes
Roadmap to Membership of RICS - Pathways and RoutesRoadmap to Membership of RICS - Pathways and Routes
Roadmap to Membership of RICS - Pathways and Routes
 
UNIT-III FMM. DIMENSIONAL ANALYSIS
UNIT-III FMM.        DIMENSIONAL ANALYSISUNIT-III FMM.        DIMENSIONAL ANALYSIS
UNIT-III FMM. DIMENSIONAL ANALYSIS
 
Call Girls Pimpri Chinchwad Call Me 7737669865 Budget Friendly No Advance Boo...
Call Girls Pimpri Chinchwad Call Me 7737669865 Budget Friendly No Advance Boo...Call Girls Pimpri Chinchwad Call Me 7737669865 Budget Friendly No Advance Boo...
Call Girls Pimpri Chinchwad Call Me 7737669865 Budget Friendly No Advance Boo...
 
UNIT-V FMM.HYDRAULIC TURBINE - Construction and working
UNIT-V FMM.HYDRAULIC TURBINE - Construction and workingUNIT-V FMM.HYDRAULIC TURBINE - Construction and working
UNIT-V FMM.HYDRAULIC TURBINE - Construction and working
 
KubeKraft presentation @CloudNativeHooghly
KubeKraft presentation @CloudNativeHooghlyKubeKraft presentation @CloudNativeHooghly
KubeKraft presentation @CloudNativeHooghly
 
Call for Papers - Educational Administration: Theory and Practice, E-ISSN: 21...
Call for Papers - Educational Administration: Theory and Practice, E-ISSN: 21...Call for Papers - Educational Administration: Theory and Practice, E-ISSN: 21...
Call for Papers - Educational Administration: Theory and Practice, E-ISSN: 21...
 
DJARUM4D - SLOT GACOR ONLINE | SLOT DEMO ONLINE
DJARUM4D - SLOT GACOR ONLINE | SLOT DEMO ONLINEDJARUM4D - SLOT GACOR ONLINE | SLOT DEMO ONLINE
DJARUM4D - SLOT GACOR ONLINE | SLOT DEMO ONLINE
 
The Most Attractive Pune Call Girls Budhwar Peth 8250192130 Will You Miss Thi...
The Most Attractive Pune Call Girls Budhwar Peth 8250192130 Will You Miss Thi...The Most Attractive Pune Call Girls Budhwar Peth 8250192130 Will You Miss Thi...
The Most Attractive Pune Call Girls Budhwar Peth 8250192130 Will You Miss Thi...
 

meetstore5.pdf

  • 3. Store is a Java library for effortless, reactive data loading. Guarantee things [you don’t want to think about] are done in the same way What is Store?
  • 4. Contracts + RELIABILITY Guarantee things are done in the same way What is Store?
  • 5. Store A brief history 2017 2019 2021 2022 2023
  • 6. Store A brief history 2017 2019 1.0 Released Jan 17th, 2017 by NY Times
  • 7. 2017 2019 Why did we need Store? We wanted to do complicated thing once
  • 8. Store Version 1.0 Api 2017 2019 Store [was] a Java library for effortless, reactive data loading built with RxJava Store<Article> Store = ParsingStoreBuilder.<BufferedSource, String>builder() .fetcher(this::ResponseAsSource) .persister(SourcePersisterFactory.create(context.getFilesDir()) .parser(GsonParserFactory.createSourceParser(gson, Article.class)) .open(); Barcode barcode = new Barcode("Article", "42"); store.get(barcode).subscribe(onNext, onError, onComplete)
  • 9. 2017 2019 Fresh == skip memory/persister go directly to fetcher store.fresh(param).subscribe(onNext, onError, onComplete) Fresh Skip Caches
  • 10. Store Why You Need User Research 2.0 Released 1 month later (oops!) 2017 2019
  • 11. 3.0 Api Rxjava2 RxSingle instead of Observable Store<Article> Store = ParsingStoreBuilder.<BufferedSource,ArticleParam, String>builder() .fetcher(this::ResponseAsSource) //responseBody.source() .persister(SourcePersisterFactory.create(context.getFilesDir()) .parser(GsonParserFactory.createSourceParser(gson, Article.class)) .open(); ArticleParam param = new ArticleParam("42"); store.get(param).subscribe(onNext, onError) 2017 2019 Store
  • 12. Coroutines have hit stable 2017 2019 2021 Fast forward to 2019
  • 13. Bye bye RxJava Hello Kotlin 2017 2019 2021 Store4 Fast forward to 2019
  • 14. Hello Kotlin 2017 2019 2021 Store4 StoreBuilder.from { api.fetchSubreddit(it, "10")} .sourceOfTruth( reader = db.postDao()::loadPosts, writer = db.postDao()::insertPosts, delete = db.postDao()::clearFeed) .cachePolicy(MemoryPolicy) .build() Api
  • 15. Streaming as first class citizen 2017 2019 2021 fun stream(request: StoreRequest<Key>): Flow<StoreResponse>Output>> lifecycleScope.launchWhenStarted { store.stream(StoreRequest.cached(3, refresh = false)) .collect{ } store.stream(StoreRequest.get(3)) .collect{ storeResponse -> } Store4 Api
  • 16. Loading|Content|Error Return Types 2017 2019 2021 Store 4 store.stream(StoreRequest.cached(key = key, refresh=true)).collect { response -> when(response) { is StoreResponse.Loading -> showLoadingSpinner() is StoreResponse.Data -> { if (response.origin == ResponseOrigin.Fetcher) hideLoadingSpinner() updateUI(response.value) } is StoreResponse.Error -> { if (response.origin == ResponseOrigin.Fetcher) hideLoadingSpinner() showError(response.error) }}}} LCE
  • 17. Using Store 4 Examples are from Firefly for Mastodon https://github.com/digitalbuddha/Firefly 2017 2019 2021
  • 18. You create a Store using a builder. The only requirement is to include a Fetcher which is just a typealias to a function that returns a Flow<FetcherResult<ReturnType>>. //build it val store = StoreBuilder.from( Fetcher.of { key: Unit -> userApi.noti fi cations( authHeader = " Bearer ${oauthRepository.getCurrent()}", offset = null) }).build() //use it store.stream(StoreRequest.cached(Unit, refresh = true)).map { it.dataOrNull() } .collect{response-> } Fetcher as a Function 2017 2019 2021
  • 19. How we get data 2017 2019 2021
  • 20. Do the hard thing once How to work with local persistence
  • 21. Source of Truth suspend fun fetcher(key:String): Token = api.createAccessToken(key) fun sourceOfTruth = SourceOfTruth.of<String, Token, String>( reader = {dataStore.data.map { it.currentUser?.accessToken }}, writer = { _, token -> dataStore.updateData { it.user.copy(accessToken = token.accessToken) }}) private val userTokenStore: Store<String, String> = StoreBuilder.from( fetcher = Fetcher.of { key: String -> fetcher(key) }, sourceOfTruth = sourceOfTruth ).build() 2017 2019 2021
  • 23. Fast forward to 2022 Where we were 365 days ago 2021 2022 2023
  • 24. Store 4 is stable Less than a dozen open bugs 2021 2022 2023
  • 25. API was perfect As long as you only asked me 2021 2022 2023
  • 26. We had LOTS of feature requests 2021 2022 2023
  • 27. That I was ignoring 2021 2022 2023
  • 32. Store 5 Introducing Store now with batteries included
  • 33.
  • 35. Sync
  • 42. Don’t worry Store 5 is a superset of Store4 Which targets JVM/iOS/Web
  • 43. How we got here…
  • 44. Try 1…Adding Write Support Rewrite what you don’t understand
  • 45. Mike: What is the bene fi t of starting over? Matt: Hmm Mike: Is it easier to add old to new or new to old?
  • 46. Some time later… (half hour) Matt: safeguards will be easier to add to new Matt: because I don’t understand old Mike: SGTM as long as all tests are migrated, I also don’t understand old Matt: Sure how hard can it be?
  • 47. Many days later: Mike: …. Matt: …
  • 48. More time passes Mike: My spider sense is tingling, I found more gaps in new Mike: let’s sit together and go through Store4 code
  • 49. Try 2…Extending the old Rather than boiling the ocean
  • 50. Few weeks later… Matt:Just finished last test cases everything passes Mike: Everything? Matt: Yup in iOS, android, JVM and JS, I took all the work https://github.com/aclassen did and got it to pass tests
  • 51.
  • 53. Mutations Con fl ict Resolution Fallback Mechanisms List Decomposition Cache Delegation Validation Concepts
  • 56.
  • 57.
  • 58.
  • 59. User Story - Hiking without Internet
  • 61. Data Pulled & Pushed
  • 62. Source of Truth to Repository Data Flow
  • 63. Can’t do with Store 4 Source of Truth to Repository Data Flow
  • 64. interface Updater<Key, Output, Response> { suspend fun post(key: Key, value: Output): UpdaterResult val onCompletion: OnUpdaterCompletion<Response>?} Store 5 New Mutation Api Creating an Updater (like a fetcher)
  • 66. val updater = Updater.by( post = { _, hike -> try { val latest = api.updateHike(hike) UpdaterResult.Success.Typed(latest) } catch (error: Throwable) { UpdaterResult.Error.Exception(error) }}) Store 5 Updater Factory
  • 67. val mutableStore = store.asMutableStore( updater = updater, bookkeeper = bookkeeper) Store 5 Mutable Store Builder
  • 68. class RealHikeManager @Inject constructor( private val mutableStore: MutableStore<Int, Hike>, private val location:locationRepository, private val map:mapRepository ): HikeManager { private suspend fun track() { combine(location.current(), map.current()) { location, map -> val request = createStoreWriteRequest(location, map) val response = mutableStore.write(request) handleResponse(response) }}} Store 5 Usage of MutableStore
  • 69. class RealHikeManager @Inject constructor( private val mutableStore: MutableStore<Int, Hike>, private val location:locationRepository, private val map:mapRepository ): HikeManager { private suspend fun track() { combine(location.current(), map.current()) { location, map -> val request = createStoreWriteRequest(location, map) val response = mutableStore.write(request) handleResponse(response) }}} Store 5 Usage of MutableStore
  • 70. What happens if write fails or a competing write?
  • 73.
  • 74. How Does Store 5 Resolves Con fl icts? Implementing Principles
  • 75. How Store 5 Resolves Conflicts We Don’t You Do! With Delegation
  • 76. What we need from you A Bookkeeper (delegate)
  • 77. Bookkeeper? Tracks when local changes fail to sync with network
  • 78. Store 5 Bookkeeper Api interface Bookkeeper<Key : Any> { suspend fun getLastFailedSync(key: Key): Long? suspend fun setLastFailedSync(key: Key, timestamp: Long): Boolean suspend fun clear(key: Key): Boolean suspend fun clearAll(): Boolean}
  • 79. MutableStore + Bookkeeper Before completing a read request, MutableStore asks Bookkeeper whether any conflicts might exist
  • 80. Store 5 - Any Conflicts? RealMutableStore private suspend fun con fl ictsMightExist(key: Key): Boolean { val lastFailedSync = bookkeeper?.getLastFailedSync(key) return lastFailedSync != null || writeRequestsQueueIsEmpty(key).not() }
  • 81. MutableStore + Bookkeeper And if conflicts might exist, MutableStore tries to eagerly resolve them
  • 82. What we think you should do Resolve conflicts on remote
  • 83. On each write request 1. Init thread safety (key-scoped) 2. Add request to stack (key-scoped) 3. Write to memory cache + SOT!!! 4. Try to update network (posting latest) Mutations In the Weeds
  • 84. On each write request 1. Init thread safety (key-scoped) 2. Add request to stack (key-scoped) 3. Write to memory cache + SOT!!! 4. Try to update network (posting latest) In the Weeds Mutations
  • 85. On each write request 1. Init thread safety (key-scoped) 2. Add request to stack (key-scoped) 3. Write to memory cache + SOT!!! 4. Try to update network (posting latest) In the Weeds Mutations
  • 86. On each write request 1. Init thread safety (key-scoped) 2. Add request to stack (key-scoped) 3. Write to memory cache + SOT!!! 4. Try to update network (posting latest) In the Weeds Mutations
  • 87. When network response 1. Success 1. Reset stack 2. Reset bookkeeper 2. Failure 1. Log with bookkeeper Try to update network
  • 88. When network response 1. Success 1. Reset stack 2. Reset bookkeeper 2. Failure 1. Log with bookkeeper Try to update network
  • 89. When network response 1. Success 1. Reset stack 2. Reset bookkeeper 2. Failure 1. Log with bookkeeper Try to update network
  • 90. When network response 1. Success 1. Reset stack 2. Reset bookkeeper 2. Failure 1. Log with bookkeeper Try to update network
  • 91. When network response 1. Success 1. Reset stack 2. Reset bookkeeper 2. Failure 1. Log with bookkeeper Try to update network
  • 93. Always have a backup plan! Fallback Mechanisms
  • 94. Store 5 Fetcher Api fun <Key : Any, Network : Any> of( name: String? = null, fetch: suspend (key: Key) -> Network ): Fetcher<Key, Network> = ofFlow(name, fetch.asFlow())
  • 95. fun <Key : Any, Network : Any> of( name: String? = null, fallback: Fetcher<Key, Network>, fetch: suspend (key: Key) -> Network ): Fetcher<Key, Network> = ofFlowWithFallback(name, fallback, fetch.asFlow()) Store 5 Fetcher Api with fallback
  • 96. User Story - A/B Testing
  • 97. data class FeatureFlag( val key: String, val name: String, val description: String, val kind: Kind, val version: Int, val creationDate: Long, ) : Identi fi able<String> { enum class Kind { Boolean, Multivariate}} Trails Feature Flag Model
  • 98. Trails Feature Flag Status Model sealed class FeatureFlagStatus: Identi fi able<String> { data class Multivariate( val key: String, val value: FeatureFlagVariation, val lastRequested: Long, val links: Links)}
  • 101. Network Feature Flag Status Fetcher With Fallback val networkFetcher = Fetcher.ofWithFallback( name = “networkFetcher”, fallback = hardcodedFetcher ) { key -> when (key) { is Collection -> fetchFeatureFlagStatuses(key.userId) is Single -> fetchFeatureFlagStatus(key.userId, key. fl agId)}}
  • 102. Hardcoded Feature Flag Status Fetcher val hardcodedFetcher = Fetcher.of( name = “hardcodedFetcher” ) { key -> when (key) { is Collection -> loadFeatureFlagStatuses(key.userId) is Single -> loadFeatureFlagStatus(key.userId, key. fl agId)}}
  • 103. Build Store as normal val store = StoreBuilder.from( fetcher = networkFetcher, sourceOfTruth = sourceOfTruth, memoryCache = multiCache ).toMutableStoreBuilder<FeatureFlagStatusData, FeatureFlagStatusData>().build( updater = updater, bookkeeper = bookkeeper)
  • 106. Just works Store Loves KMP We target Android/ Desktop/iOS/JS
  • 107. Store 5 Beta is out now github.com/mobilenativefoundation/store