*(kind of)
standard library
kotlinx-coroutines
launch, async, runBlocking, future, delay, Job, Deferred...
fun postItem(item: Item) {
preparePostAsync { token ->
submitPostAsync(token, item) { post ->
processPost(post)
}
}
}fun postItem(item: Item) {
preparePostAsync { token ->
submitPostAsync(token, item) { post ->
processPost(post)
}
}
}fun postItem(item: Item) {
validateWithExternalService { item ->
preparePostAsync { token ->
submitPostAsync(token, item) { post ->
processPost(post)
}
}
}
}fun postItem(item: Item) {
validateWithExternalService { item ->
preparePostAsync { token ->
submitPostAsync(token, item) { post ->
processPost(post)
}
}
}
}fun postItem(item: Item) {
preparePostAsync()
.thenCompose { token ->
submitPostAsync(token, item)
}
.thenAccept { post ->
processPost(post)
}
}
fun postItem(item: Item) {
validateWithExternalService(item)
.thenCompose { item ->
preparePostAsync(item)
}
.thenCompose { token ->
submitPostAsync(token, item)
}
.thenAccept { post ->
processPost(post)
}
}fun postItem(item: Item) {
validateWithExternalService(item)
.thenCompose { item ->
preparePostAsync(item)
}
.thenCompose { token ->
submitPostAsync(token, item)
}
.thenAccept { post ->
processPost(post)
}
}fun postItem(item: Item) {
launch {
val token = preparePost()
val post = submitPost(token, item)
processPost(post)
}
}
fun postItem(item: Item) {
launch {
val item = validateWithExternalService(item)
val token = preparePost()
val post = submitPost(token, item)
processPost(post)
}
}
fun postItem(item: Item) {
launch {
val item = validateWithExternalService(item)
val token = preparePost()
val post = submitPost(token, item)
processPost(post)
}
}
[
{
"id": 8856204,
"node_id": "MDEwOlJlcG9zaXRvcnk4ODU2MjA0",
"name": "kotlin-examples",
"full_name": "Kotlin/kotlin-examples",
"private": false,
"owner": {
"login": "Kotlin",
"id": 1446536,
"node_id": "MDEyOk9yZ2FuaXphdGlvbjE0NDY1MzY=",
"avatar_url": "https://avatars3.githubusercontent.com/u/1446536?v=4",
"gravatar_id": "",
"url": "https://api.github.com/users/Kotlin",
"html_url": "https://github.com/Kotlin",
"followers_url": "https://api.github.com/users/Kotlin/followers",
"following_url": "https://api.github.com/users/Kotlin/following{/other_user}",
"gists_url": "https://api.github.com/users/Kotlin/gists{/gist_id}",
"starred_url": "https://api.github.com/users/Kotlin/starred{/owner}{/repo}",
"subscriptions_url": "https://api.github.com/users/Kotlin/subscriptions",
"organizations_url": "https://api.github.com/users/Kotlin/orgs",
"repos_url": "https://api.github.com/users/Kotlin/repos",
"events_url": "https://api.github.com/users/Kotlin/events{/privacy}",
"received_events_url": "https://api.github.com/users/Kotlin/received_events",
"type": "Organization",
"site_admin": false
},
"html_url": "https://github.com/Kotlin/kotlin-examples",
"description": "Various examples for Kotlin",
"fork": false,
"url": "https://api.github.com/repos/Kotlin/kotlin-examples",
"forks_url": "https://api.github.com/repos/Kotlin/kotlin-examples/forks",
"keys_url": "https://api.github.com/repos/Kotlin/kotlin-examples/keys{/key_id}",
"repos_url": "https://api.github.com/users/Kotlin/repos",
"events_url": "https://api.github.com/users/Kotlin/events{/privacy}",
"received_events_url": "https://api.github.com/users/Kotlin/received_events",[
{
"id": 8856204,
"node_id": "MDEwOlJlcG9zaXRvcnk4ODU2MjA0",
"name": "kotlin-examples",
"full_name": "Kotlin/kotlin-examples",
"private": false,
"owner": {
"login": "Kotlin",
"id": 1446536,
"node_id": "MDEyOk9yZ2FuaXphdGlvbjE0NDY1MzY=",
"avatar_url": "https://avatars3.githubusercontent.com/u/1446536?v=4",
"gravatar_id": "",
"url": "https://api.github.com/users/Kotlin",
"html_url": "https://github.com/Kotlin",
"followers_url": "https://api.github.com/users/Kotlin/followers",
"following_url": "https://api.github.com/users/Kotlin/following{/other_user}",
"gists_url": "https://api.github.com/users/Kotlin/gists{/gist_id}",
"starred_url": "https://api.github.com/users/Kotlin/starred{/owner}{/repo}",
"subscriptions_url": "https://api.github.com/users/Kotlin/subscriptions",
"organizations_url": "https://api.github.com/users/Kotlin/orgs",
"repos_url": "https://api.github.com/users/Kotlin/repos",
"events_url": "https://api.github.com/users/Kotlin/events{/privacy}",
"received_events_url": "https://api.github.com/users/Kotlin/received_events",
"type": "Organization",
"site_admin": false
},
"html_url": "https://github.com/Kotlin/kotlin-examples",
"description": "Various examples for Kotlin",
"fork": false,
"url": "https://api.github.com/repos/Kotlin/kotlin-examples",
"forks_url": "https://api.github.com/repos/Kotlin/kotlin-examples/forks",
"keys_url": "https://api.github.com/repos/Kotlin/kotlin-examples/keys{/key_id}",
"repos_url": "https://api.github.com/users/Kotlin/repos",
"events_url": "https://api.github.com/users/Kotlin/events{/privacy}",
"received_events_url": "https://api.github.com/users/Kotlin/received_events",[
{
"login": "jonnyzzz",
"id": 256431,
"node_id": "MDQ6VXNlcjI1NjQzMQ==",
"avatar_url": "https://avatars3.githubusercontent.com/u/256431?v=4",
"gravatar_id": "",
"url": "https://api.github.com/users/jonnyzzz",
"html_url": "https://github.com/jonnyzzz",
"followers_url": "https://api.github.com/users/jonnyzzz/followers",
"following_url": "https://api.github.com/users/jonnyzzz/following{/other_user}",
"gists_url": "https://api.github.com/users/jonnyzzz/gists{/gist_id}",
"starred_url": "https://api.github.com/users/jonnyzzz/starred{/owner}{/repo}",
"repos_url": "https://api.github.com/users/jonnyzzz/repos",
"events_url": "https://api.github.com/users/jonnyzzz/events{/privacy}",
"received_events_url": "https://api.github.com/users/jonnyzzz/received_events",
"type": "User",
"site_admin": false,
"contributions": 54
},
{
"login": "yanex",
"id": 95996,
"node_id": "MDQ6VXNlcjk1OTk2",
"avatar_url": "https://avatars2.githubusercontent.com/u/95996?v=4",
"gravatar_id": "",
"url": "https://api.github.com/users/yanex",
"html_url": "https://github.com/yanex",
"followers_url": "https://api.github.com/users/yanex/followers",
"following_url": "https://api.github.com/users/yanex/following{/other_user}",
"gists_url": "https://api.github.com/users/yanex/gists{/gist_id}",
"starred_url": "https://api.github.com/users/yanex/starred{/owner}{/repo}",
"repos_url": "https://api.github.com/users/yanex/repos",
"events_url": "https://api.github.com/users/yanex/events{/privacy}",
"received_events_url": "https://api.github.com/users/yanex/received_events",
"type": "User",
"site_admin": false,
"contributions": 47
},
{
"login": "yole",
"id": 46553,(utilizaremos o HTTP client retrofit)
interface GitHubService {
@GET("orgs/{org}/repos?per_page=100")
fun getOrgReposCall(
@Path("org") org: String
): Call<List<Repo>>
@GET("repos/{org}/{repo}/contributors?per_page=100")
fun getRepoContributorsCall(
@Path("org") org: String,
@Path("repo") repo: String
): Call<List<User>>
}val users = loadContributorsBlocking(service, req)
updateResults(users)fun loadContributorsBlocking(service: GitHubService, req: RequestData) : List<User> {
val repos: list<Repo> = service
.getOrgReposCall(req.org)
.execute() // blocks current thread
.also { logRepos(req, it) }
.body() ?: listOf()
return repos.flatMap { repo ->
service
.getRepoContributorsCall(req.org, repo.name)
.execute() // blocks current thread
.also { logUsers(repo, it) }
.bodyList()
}.aggregate()
}interface GitHubService {
@GET("orgs/{org}/repos?per_page=100")
fun getOrgReposCall(
@Path("org") org: String
): Call<List<Repo>>
@GET("repos/{org}/{repo}/contributors?per_page=100")
fun getRepoContributorsCall(
@Path("org") org: String,
@Path("repo") repo: String
): Call<List<User>>
}interface GitHubService {
@GET("orgs/{org}/repos?per_page=100")
suspend fun getOrgReposCall(
@Path("org") org: String
): Call<List<Repo>>
@GET("repos/{org}/{repo}/contributors?per_page=100")
suspend fun getRepoContributorsCall(
@Path("org") org: String,
@Path("repo") repo: String
): Call<List<User>>
}fun loadContributorsSuspend(service: GitHubService, req: RequestData): List<User> {
val repos = service
.getOrgRepos(req.org)
.also { logRepos(req, it) }
.body() ?: listOf()
return repos.flatMap { repo ->
service
.getRepoContributors(req.org, repo.name)
.also { logUsers(repo, it) }
.bodyList()
}.aggregate()
}suspend fun loadContributorsSuspend(service: GitHubService, req: RequestData): List<User> {
val repos = service
.getOrgRepos(req.org)
.also { logRepos(req, it) }
.body() ?: listOf()
return repos.flatMap { repo ->
service
.getRepoContributors(req.org, repo.name)
.also { logUsers(repo, it) }
.bodyList()
}.aggregate()
}val users = loadContributorsSuspend(service, req)
updateResults(users)launch {
val users = loadContributorsSuspend(service, req)
updateResults(users, startTime)
}why
suspend fun loadContributorsSuspend(service: GitHubService, req: RequestData): List<User> {
val repos = service
.getOrgRepos(req.org)
.also { logRepos(req, it) }
.body() ?: listOf()
return repos.flatMap { repo ->
service
.getRepoContributors(req.org, repo.name)
.also { logUsers(repo, it) }
.bodyList()
}.aggregate()
}suspend fun loadContributorsSuspend(service: GitHubService, req: RequestData): List<User> {
val repos = service
.getOrgRepos(req.org)
.also { logRepos(req, it) }
.body() ?: listOf()
return repos.flatMap { repo ->
service
.getRepoContributors(req.org, repo.name)
.also { logUsers(repo, it) }
.bodyList()
}.aggregate()
}suspend fun loadContributorsSuspend(service: GitHubService, req: RequestData): List<User> {
val repos = service
.getOrgRepos(req.org)
.also { logRepos(req, it) }
.body() ?: listOf()
val deferreds = repos.map { repo ->
async {
service
.getRepoContributors(req.org, repo.name)
.also { logUsers(repo, it) }
.bodyList()
}
}
}suspend fun loadContributorsSuspend(service: GitHubService, req: RequestData): List<User> {
val repos = service
.getOrgRepos(req.org)
.also { logRepos(req, it) }
.body() ?: listOf()
val deferreds = repos.map { repo ->
async {
service
.getRepoContributors(req.org, repo.name)
.also { logUsers(repo, it) }
.bodyList()
}
}
}suspend fun loadContributorsSuspend(service: GitHubService, req: RequestData): List<User> {
val repos = service
.getOrgRepos(req.org)
.also { logRepos(req, it) }
.body() ?: listOf()
// deferreds é uma List<Deferred<List<User>>>
val deferreds = repos.map { repo ->
async {
service
.getRepoContributors(req.org, repo.name)
.also { logUsers(repo, it) }
.bodyList()
}
}
}suspend fun loadContributorsSuspend(service: GitHubService, req: RequestData): List<User> {
val repos = service
.getOrgRepos(req.org)
.also { logRepos(req, it) }
.body() ?: listOf()
// deferreds é uma List<Deferred<List<User>>>
val deferreds = repos.map { repo ->
async {
service
.getRepoContributors(req.org, repo.name)
.also { logUsers(repo, it) }
.bodyList()
}
}
}o objeto deferred tem o método await()
suspend fun loadContributorsSuspend(service: GitHubService, req: RequestData): List<User> {
val repos = service
.getOrgRepos(req.org)
.also { logRepos(req, it) }
.body() ?: listOf()
// deferreds é uma List<Deferred<List<User>>>
val deferreds = repos.map { repo ->
async {
service
.getRepoContributors(req.org, repo.name)
.also { logUsers(repo, it) }
.bodyList()
}
}
}uma list de deferreds tem o método awaitAll()
suspend fun loadContributorsSuspend(service: GitHubService, req: RequestData): List<User> {
val repos = service
.getOrgRepos(req.org)
.also { logRepos(req, it) }
.body() ?: listOf()
// deferreds é uma List<Deferred<List<User>>>
val deferreds = repos.map { repo ->
async {
service
.getRepoContributors(req.org, repo.name)
.also { logUsers(repo, it) }
.bodyList()
}
}
deferreds.awaitAll()
}suspend fun loadContributorsSuspend(service: GitHubService, req: RequestData): List<User> {
val repos = service
.getOrgRepos(req.org)
.also { logRepos(req, it) }
.body() ?: listOf()
// deferreds é uma List<Deferred<List<User>>>
val deferreds = repos.map { repo ->
async {
service
.getRepoContributors(req.org, repo.name)
.also { logUsers(repo, it) }
.bodyList()
}
}
deferreds.awaitAll().flatten().aggregate()
}suspend fun loadContributorsSuspend(service: GitHubService, req: RequestData): List<User> {
val repos = service
.getOrgRepos(req.org)
.also { logRepos(req, it) }
.body() ?: listOf()
// deferreds é uma List<Deferred<List<User>>>
val deferreds = repos.map { repo ->
async {
service
.getRepoContributors(req.org, repo.name)
.also { logUsers(repo, it) }
.bodyList()
}
}
return deferreds.awaitAll().flatten().aggregate()
}suspend fun loadContributorsChannels(service: GitHubService, req: RequestData): List<User> {
val repos = service
.getOrgRepos(req.org)
.also { logRepos(req, it) }
.body() ?: listOf()
val deferreds = repos.map { repo ->
async {
service
.getRepoContributors(req.org, repo.name)
.also { logUsers(repo, it) }
.bodyList()
}
}
return deferreds.awaitAll().flatten().aggregate()
}suspend fun loadContributorsChannels(service: GitHubService, req: RequestData): List<User> {
val repos = service
.getOrgRepos(req.org)
.also { logRepos(req, it) }
.body() ?: listOf()
/*val deferreds = repos.map { repo ->
async {
service
.getRepoContributors(req.org, repo.name)
.also { logUsers(repo, it) }
.bodyList()
}
}
return deferreds.awaitAll().flatten().aggregate()*/
}suspend fun loadContributorsChannels(service: GitHubService, req: RequestData) {
val repos = service
.getOrgRepos(req.org)
.also { logRepos(req, it) }
.body() ?: listOf()
}suspend fun loadContributorsChannels(service: GitHubService, req: RequestData) {
val repos = service
.getOrgRepos(req.org)
.also { logRepos(req, it) }
.body() ?: listOf()
val channel = Channel<List<User>>()
}suspend fun loadContributorsChannels(service: GitHubService, req: RequestData) {
val repos = service
.getOrgRepos(req.org)
.also { logRepos(req, it) }
.body() ?: listOf()
val channel = Channel<List<User>>()
for (repo in repos) {
launch {
val users = service
.getRepoContributors(req.org, repo.name)
.bodyList()
channel.send(users)
}
}
}suspend fun loadContributorsChannels(service: GitHubService, req: RequestData) {
val repos = service
.getOrgRepos(req.org)
.also { logRepos(req, it) }
.body() ?: listOf()
val channel = Channel<List<User>>()
for (repo in repos) { // pra cada repo
launch { // lançamos uma coroutine nova
val users = service
.getRepoContributors(req.org, repo.name)
.bodyList()
channel.send(users) // e enviamos o result aqui
}
}
}suspend fun loadContributorsChannels(service: GitHubService, req: RequestData) {
val repos = service
.getOrgRepos(req.org)
.also { logRepos(req, it) }
.body() ?: listOf()
val channel = Channel<List<User>>()
for (repo in repos) { // pra cada repo
launch { // lançamos uma coroutine nova
val users = service
.getRepoContributors(req.org, repo.name)
.bodyList()
channel.send(users) // e enviamos o result aqui
}
}
var allUsers = emptyList<User>()
repeat(repos.size) {
val users = channel.receive()
allUsers = (allUsers + users).aggregate()
}
}suspend fun loadContributorsChannels(service: GitHubService, req: RequestData) {
val repos = service
.getOrgRepos(req.org)
.also { logRepos(req, it) }
.body() ?: listOf()
val channel = Channel<List<User>>()
for (repo in repos) { // pra cada repo
launch { // lançamos uma coroutine nova
val users = service
.getRepoContributors(req.org, repo.name)
.bodyList()
channel.send(users) // e enviamos o result aqui
}
}
var allUsers = emptyList<User>()
repeat(repos.size) {
val users = channel.receive() // pra cada mensagem recebida
allUsers = (allUsers + users).aggregate() // somamos os resultados
// mas como atualizamos a GUI??
}
}suspend fun loadContributorsChannels(service: GitHubService, req: RequestData) {
val repos = service
.getOrgRepos(req.org)
.also { logRepos(req, it) }
.body() ?: listOf()
val channel = Channel<List<User>>()
for (repo in repos) { // pra cada repo
launch { // lançamos uma coroutine nova
val users = service
.getRepoContributors(req.org, repo.name)
.bodyList()
channel.send(users) // e enviamos o result aqui
}
}
var allUsers = emptyList<User>()
repeat(repos.size) {
val users = channel.receive() // pra cada mensagem recebida
allUsers = (allUsers + users).aggregate() // somamos os resultados
// vamos chamar a função de atualização aqui, recebendo ela como parametro nessa função aqui!
}
}suspend fun loadContributorsChannels(service: GitHubService, req: RequestData) {
val repos = service
.getOrgRepos(req.org)
.also { logRepos(req, it) }
.body() ?: listOf()
val channel = Channel<List<User>>()
for (repo in repos) { // pra cada repo
launch { // lançamos uma coroutine nova
val users = service
.getRepoContributors(req.org, repo.name)
.bodyList()
channel.send(users) // e enviamos o result aqui
}
}
var allUsers = emptyList<User>()
repeat(repos.size) {
val users = channel.receive()
allUsers = (allUsers + users).aggregate()
//TODO: update GUI
}
}suspend fun loadContributorsChannels(service: GitHubService, req: RequestData, updateResults: suspend (List<User>, completed: Boolean)) {
val repos = service
.getOrgRepos(req.org)
.also { logRepos(req, it) }
.body() ?: listOf()
val channel = Channel<List<User>>()
for (repo in repos) { // pra cada repo
launch { // lançamos uma coroutine nova
val users = service
.getRepoContributors(req.org, repo.name)
.bodyList()
channel.send(users) // e enviamos o result aqui
}
}
var allUsers = emptyList<User>()
repeat(repos.size) {
val users = channel.receive()
allUsers = (allUsers + users).aggregate()
//TODO: update GUI
}
}suspend fun loadContributorsChannels(service: GitHubService, req: RequestData, updateResults: suspend (List<User>, completed: Boolean)) {
val repos = service
.getOrgRepos(req.org)
.also { logRepos(req, it) }
.body() ?: listOf()
val channel = Channel<List<User>>()
for (repo in repos) { // pra cada repo
launch { // lançamos uma coroutine nova
val users = service
.getRepoContributors(req.org, repo.name)
.bodyList()
channel.send(users) // e enviamos o result aqui
}
}
var allUsers = emptyList<User>()
repeat(repos.size) {
val users = channel.receive()
allUsers = (allUsers + users).aggregate()
updateResults(allUsers, it == repos.lastIndex)
}
}launch {
val users = loadContributorsChannels(service, req)
updateResults(users, startTime)
}launch {
val users = loadContributorsChannels(service, req) { users, completed ->
updateResults(users, completed)
}
}launch {
loadContributorsChannels(service, req) { users, completed ->
updateResults(users, completed)
}
}