SlideShare a Scribd company logo
1 of 64
Download to read offline
⽤用 Go 語⾔言
打造多台機器 Scale 架構
Bo-Yi Wu
2020/09/08
About me
• Software Engineer in Mediatek
• Member of Drone CI/CD Platform
• Member of Gitea Platform
• Member of Gin Golang Framework
• Maintain Some GitHub Actions Plugins.
• Teacher of Udemy Platform: Golang + Drone
NeuroPilot
MediaTek Ecosystem for AI Development
https://neuropilot.mediatek.com/
專案需求
• 客⼾戶單機版 (Docker 版本)
• 內建簡易易的 Queue 機制
• 公司內部架構 (軟體 + 硬體)
• 多台 Queue 機制 + 硬體模擬
每個 Job 吃 2core 8GB 記憶體
為什什麼選 Go 語⾔言
• 公司環境限制
• 保護程式邏輯
• 跨平台編譯 (Windows, Linux)
• 強⼤大 Concurrency
客⼾戶單機版
導入 Queue 機制
RabbitMQ
NSQ
Service 部分元件
• Database: SQLite (不需要 MySQL, Postgres)
• Cache: Memory (不需要 Redis)
• Queue: ⾃自⾏行行開發
客⼾戶 IT 環境
如何實作簡易易的
Queue 機制
每個 Job 吃 2core 8GB 記憶體
先了了解
Channel Blocking
https://utcc.utoronto.ca/~cks/space/blog/programming/GoConcurrencyStillNotEasy
Limit Concurrency Issue
found	:=	make(chan	int)	
			limitCh	:=	make(chan	struct{},	concurrencyProcesses)	
			for	i	:=	0;	i	<	jobCount;	i++	{	
							limitCh	<-	struct{}{}	
							go	func(val	int)	{	
											defer	func()	{	
															wg.Done()	
															<-limitCh	
											}()	
											found	<-	val	
							}(i)	
			}
jobCount = 100
concurrencyProcesses = 10
found	:=	make(chan	int)	
			limitCh	:=	make(chan	struct{},	concurrencyProcesses)	
			for	i	:=	0;	i	<	jobCount;	i++	{	
							limitCh	<-	struct{}{}	
							go	func(val	int)	{	
											defer	func()	{	
															wg.Done()	
															<-limitCh	
											}()	
											found	<-	val	
							}(i)	
			}
jobCount = 100
concurrencyProcesses = 10
解決⽅方案
將 limitCh 丟到背景處理理?
found	:=	make(chan	int)	
			limitCh	:=	make(chan	struct{},	concurrencyProcesses)	
			for	i	:=	0;	i	<	jobCount;	i++	{	
							go	func()	{	
											limitCh	<-	struct{}{}	
							}()	
							go	func(val	int)	{	
											defer	func()	{	
															<-limitCh	
															wg.Done()	
											}()	
											found	<-	val	
							}(i)	
			}
jobCount = 100
concurrencyProcesses = 10
found	:=	make(chan	int)	
			limitCh	:=	make(chan	struct{},	concurrencyProcesses)	
			for	i	:=	0;	i	<	jobCount;	i++	{	
							go	func()	{	
											limitCh	<-	struct{}{}	
							}()	
							go	func(val	int)	{	
											defer	func()	{	
															<-limitCh	
															wg.Done()	
											}()	
											found	<-	val	
							}(i)	
			}
無法解決 Limit Concurrency
jobCount = 100
concurrencyProcesses = 10
解決⽅方案
重新改寫架構
found	:=	make(chan	int)	
		queue	:=	make(chan	int)	
		go	func(queue	chan<-	int)	{	
								for	i	:=	0;	i	<	jobCount;	i++	{	
												queue	<-	i	
								}	
								close(queue)	
				}(queue)
				for	i	:=	0;	i	<	concurrencyProcesses;	i++	{	
								go	func(queue	<-chan	int,	found	chan<-	int)	{	
												for	val	:=	range	queue	{	
																defer	wg.Done()	
																found	<-	val	
												}	
								}(queue,	found)	
				}
jobCount = 100
concurrencyProcesses = 10
Internal Queue
單機版
Setup Consumer
type Consumer struct {
inputChan chan int
jobsChan chan int
}
const PoolSize = 200
func main() {
// create the consumer
consumer := Consumer{
inputChan: make(chan int, 1),
jobsChan: make(chan int, PoolSize),
}
}
func (c *Consumer) queue(input int) {
fmt.Println("send input value:", input)
c.jobsChan <- input
}
func (c *Consumer) worker(num int) {
for job := range c.jobsChan {
fmt.Println("worker:", num, " job value:", job)
}
}
for i := 0; i < WorkerSize; i++ {
go consumer.worker(i)
}
rewrite queue func
func (c *Consumer) queue(input int) bool {
fmt.Println("send input value:", input)
select {
case c.jobsChan <- input:
return true
default:
return false
}
}
避免使⽤用者⼤大量量送資料進來來
Shutdown with
Sigterm Handling
func WithContextFunc(ctx context.Context, f func()) context.Context {
ctx, cancel := context.WithCancel(ctx)
go func() {
c := make(chan os.Signal)
signal.Notify(c, syscall.SIGINT, syscall.SIGTERM)
defer signal.Stop(c)
select {
case <-ctx.Done():
case <-c:
f()
cancel()
}
}()
return ctx
}
func (c Consumer) startConsumer(ctx context.Context) {
for {
select {
case job := <-c.inputChan:
if ctx.Err() != nil {
close(c.jobsChan)
return
}
c.jobsChan <- job
case <-ctx.Done():
close(c.jobsChan)
return
}
}
}
select 不保證讀取 Channel 的順序性
Cancel by ctx.Done() event
func (c *Consumer) worker(num int) {
for job := range c.jobsChan {
fmt.Println("worker:", num, " job value:", job)
}
}
Channel 關閉後,還是可以讀取資料到結束
Graceful shutdown
with worker
sync.WaitGroup
wg := &sync.WaitGroup{}
wg.Add(WorkerSize)
// Start [PoolSize] workers
for i := 0; i < WorkerSize; i++ {
go consumer.worker(i)
}
WaitGroup
WaitGroup
WaitGroup
WaitGroup
func (c Consumer) worker(wg *sync.WaitGroup) {
defer wg.Done()
for job := range c.jobsChan {
// handle the job event
}
}
Add WaitGroup
after Cancel Function
func WithContextFunc(ctx context.Context, f func()) context.Context {
ctx, cancel := context.WithCancel(ctx)
go func() {
c := make(chan os.Signal)
signal.Notify(c, syscall.SIGINT, syscall.SIGTERM)
defer signal.Stop(c)
select {
case <-ctx.Done():
case <-c:
cancel()
f()
}
}()
return ctx
}
Add WaitGroup after Cancel Function
wg := &sync.WaitGroup{}
wg.Add(numberOfWorkers)
ctx := signal.WithContextFunc(
context.Background(),
func() {
wg.Wait()
close(finishChan)
},
)
go consumer.startConsumer(ctx)
End of Program
select {
case <-finished:
case err := <-errChannel:
if err != nil {
return err
}
}
單機版限制
系統資源不⾜足
系統架構
Server - Agent
Server 跟 Agent 溝通方式
https://github.com/hashicorp/go-retryablehttp
r := e.Group("/rpc")
r.Use(rpc.Check())
{
r.POST("/v1/healthz", web.RPCHeartbeat)
r.POST("/v1/request", web.RPCRquest)
r.POST("/v1/accept", web.RPCAccept)
r.POST("/v1/details", web.RPCDetails)
r.POST("/v1/updateStatus", web.RPCUpdateStatus)
r.POST("/v1/upload", web.RPCUploadBytes)
r.POST("/v1/reset", web.RPCResetStatus)
}
Check RPC Secret
/rpc/v1/accept
Update jobs set version = (oldVersion + 1)
where machine = "fooBar" and version = oldVersion
Create multiple worker
if r.Capacity != 0 {
var g errgroup.Group
for i := 0; i < r.Capacity; i++ {
g.Go(func() error {
return r.start(ctx, 0)
})
time.Sleep(1 * time.Second)
}
return g.Wait()
}
單機版設定多個 Worker
for {
var (
id int64
err error
)
if id, err = r.request(ctx); err != nil {
time.Sleep(1 * time.Second)
continue
}
go func() {
if err := r.start(ctx, id); err != nil {
log.Error().Err(err).Msg("runner: cannot start the job")
}
}()
}
公司內部 + Submit Job
Break for and select loop
func (r *Runner) start(ctx context.Context, id int64) error {
LOOP:
for {
select {
case <-ctx.Done():
return ctx.Err()
default:
r.poll(ctx, id)
if r.Capacity == 0 {
break LOOP
}
}
time.Sleep(1 * time.Second)
}
return nil
}
即時取消正在執⾏行行的任務?
Context with Cancel or Timeout
ctx, cancel := context.WithCancel(context.Background())
defer cancel()
timeout, cancel := context.WithTimeout(ctx, 60*time.Minute)
defer cancel()
Job03 context
Context with Cancel or Timeout
ctx, cancel := context.WithCancel(context.Background())
defer cancel()
timeout, cancel := context.WithTimeout(ctx, 60*time.Minute)
defer cancel()
Job03 context
Job05 context
Watch the Cancel event (Agent)
go func() {
done, _ := r.Manager.Watch(ctx, id)
if done {
cancel()
}
}()
Handle cancel event on Server
subscribers: make(map[chan struct{}]int64),
cancelled: make(map[int64]time.Time),
User cancel running job
c.Lock()
c.cancelled[id] = time.Now().Add(time.Minute * 5)
for subscriber, build := range c.subscribers {
if id == build {
close(subscriber)
}
}
c.Unlock()
Agent subscribe the cancel event
for {
select {
case <-ctx.Done():
return false, ctx.Err()
case <-time.After(time.Minute):
c.Lock()
_, ok := c.cancelled[id]
c.Unlock()
if ok {
return true, nil
}
case <-subscriber:
return true, nil
}
}
case <-time.After(time.Minute):
c.Lock()
_, ok := c.cancelled[id]
c.Unlock()
if ok {
return true, nil
}
case <-time.After(time.Minute):
c.Lock()
_, ok := c.cancelled[id]
c.Unlock()
if ok {
return true, nil
}
1 Cancel
case <-time.After(time.Minute):
c.Lock()
_, ok := c.cancelled[id]
c.Unlock()
if ok {
return true, nil
}
1
2 Reconnect Server
Cancel
感謝參參與

More Related Content

What's hot

Streams are Awesome - (Node.js) TimesOpen Sep 2012
Streams are Awesome - (Node.js) TimesOpen Sep 2012 Streams are Awesome - (Node.js) TimesOpen Sep 2012
Streams are Awesome - (Node.js) TimesOpen Sep 2012
Tom Croucher
 
Using Node.js to Build Great Streaming Services - HTML5 Dev Conf
Using Node.js to  Build Great  Streaming Services - HTML5 Dev ConfUsing Node.js to  Build Great  Streaming Services - HTML5 Dev Conf
Using Node.js to Build Great Streaming Services - HTML5 Dev Conf
Tom Croucher
 

What's hot (20)

Streams are Awesome - (Node.js) TimesOpen Sep 2012
Streams are Awesome - (Node.js) TimesOpen Sep 2012 Streams are Awesome - (Node.js) TimesOpen Sep 2012
Streams are Awesome - (Node.js) TimesOpen Sep 2012
 
Using Node.js to Build Great Streaming Services - HTML5 Dev Conf
Using Node.js to  Build Great  Streaming Services - HTML5 Dev ConfUsing Node.js to  Build Great  Streaming Services - HTML5 Dev Conf
Using Node.js to Build Great Streaming Services - HTML5 Dev Conf
 
Profiling and optimizing go programs
Profiling and optimizing go programsProfiling and optimizing go programs
Profiling and optimizing go programs
 
RestMQ - HTTP/Redis based Message Queue
RestMQ - HTTP/Redis based Message QueueRestMQ - HTTP/Redis based Message Queue
RestMQ - HTTP/Redis based Message Queue
 
How to Write Node.js Module
How to Write Node.js ModuleHow to Write Node.js Module
How to Write Node.js Module
 
Bridge TensorFlow to run on Intel nGraph backends (v0.4)
Bridge TensorFlow to run on Intel nGraph backends (v0.4)Bridge TensorFlow to run on Intel nGraph backends (v0.4)
Bridge TensorFlow to run on Intel nGraph backends (v0.4)
 
PyCon KR 2019 sprint - RustPython by example
PyCon KR 2019 sprint  - RustPython by examplePyCon KR 2019 sprint  - RustPython by example
PyCon KR 2019 sprint - RustPython by example
 
Puppet and Openshift
Puppet and OpenshiftPuppet and Openshift
Puppet and Openshift
 
GraphQL IN Golang
GraphQL IN GolangGraphQL IN Golang
GraphQL IN Golang
 
Node.js/io.js Native C++ Addons
Node.js/io.js Native C++ AddonsNode.js/io.js Native C++ Addons
Node.js/io.js Native C++ Addons
 
HHVM: Efficient and Scalable PHP/Hack Execution / Guilherme Ottoni (Facebook)
HHVM: Efficient and Scalable PHP/Hack Execution / Guilherme Ottoni (Facebook)HHVM: Efficient and Scalable PHP/Hack Execution / Guilherme Ottoni (Facebook)
HHVM: Efficient and Scalable PHP/Hack Execution / Guilherme Ottoni (Facebook)
 
Node.js streaming csv downloads proxy
Node.js streaming csv downloads proxyNode.js streaming csv downloads proxy
Node.js streaming csv downloads proxy
 
Taking Jenkins Pipeline to the Extreme
Taking Jenkins Pipeline to the ExtremeTaking Jenkins Pipeline to the Extreme
Taking Jenkins Pipeline to the Extreme
 
node.js and native code extensions by example
node.js and native code extensions by examplenode.js and native code extensions by example
node.js and native code extensions by example
 
KubeCon EU 2016: Getting the Jobs Done With Kubernetes
KubeCon EU 2016: Getting the Jobs Done With KubernetesKubeCon EU 2016: Getting the Jobs Done With Kubernetes
KubeCon EU 2016: Getting the Jobs Done With Kubernetes
 
High Performance tDiary
High Performance tDiaryHigh Performance tDiary
High Performance tDiary
 
Streams for the Web
Streams for the WebStreams for the Web
Streams for the Web
 
Ruby meets Go
Ruby meets GoRuby meets Go
Ruby meets Go
 
Source Plugins
Source PluginsSource Plugins
Source Plugins
 
Nodejs Explained with Examples
Nodejs Explained with ExamplesNodejs Explained with Examples
Nodejs Explained with Examples
 

Similar to 用 Go 語言打造多台機器 Scale 架構

Jdk 7 4-forkjoin
Jdk 7 4-forkjoinJdk 7 4-forkjoin
Jdk 7 4-forkjoin
knight1128
 
服务框架: Thrift & PasteScript
服务框架: Thrift & PasteScript服务框架: Thrift & PasteScript
服务框架: Thrift & PasteScript
Qiangning Hong
 

Similar to 用 Go 語言打造多台機器 Scale 架構 (20)

如何透過 Go-kit 快速搭建微服務架構應用程式實戰
如何透過 Go-kit 快速搭建微服務架構應用程式實戰如何透過 Go-kit 快速搭建微服務架構應用程式實戰
如何透過 Go-kit 快速搭建微服務架構應用程式實戰
 
gRPC in Go
gRPC in GogRPC in Go
gRPC in Go
 
Refactoring for testability c++
Refactoring for testability c++Refactoring for testability c++
Refactoring for testability c++
 
JVM Mechanics: When Does the JVM JIT & Deoptimize?
JVM Mechanics: When Does the JVM JIT & Deoptimize?JVM Mechanics: When Does the JVM JIT & Deoptimize?
JVM Mechanics: When Does the JVM JIT & Deoptimize?
 
CGI.ppt
CGI.pptCGI.ppt
CGI.ppt
 
RxJava on Android
RxJava on AndroidRxJava on Android
RxJava on Android
 
A deep dive into PEP-3156 and the new asyncio module
A deep dive into PEP-3156 and the new asyncio moduleA deep dive into PEP-3156 and the new asyncio module
A deep dive into PEP-3156 and the new asyncio module
 
LSFMM 2019 BPF Observability
LSFMM 2019 BPF ObservabilityLSFMM 2019 BPF Observability
LSFMM 2019 BPF Observability
 
Jdk 7 4-forkjoin
Jdk 7 4-forkjoinJdk 7 4-forkjoin
Jdk 7 4-forkjoin
 
Category theory, Monads, and Duality in the world of (BIG) Data
Category theory, Monads, and Duality in the world of (BIG) DataCategory theory, Monads, and Duality in the world of (BIG) Data
Category theory, Monads, and Duality in the world of (BIG) Data
 
服务框架: Thrift & PasteScript
服务框架: Thrift & PasteScript服务框架: Thrift & PasteScript
服务框架: Thrift & PasteScript
 
[grcpp] Refactoring for testability c++
[grcpp] Refactoring for testability c++[grcpp] Refactoring for testability c++
[grcpp] Refactoring for testability c++
 
Osol Pgsql
Osol PgsqlOsol Pgsql
Osol Pgsql
 
The Ring programming language version 1.10 book - Part 10 of 212
The Ring programming language version 1.10 book - Part 10 of 212The Ring programming language version 1.10 book - Part 10 of 212
The Ring programming language version 1.10 book - Part 10 of 212
 
Silicon Valley JUG: JVM Mechanics
Silicon Valley JUG: JVM MechanicsSilicon Valley JUG: JVM Mechanics
Silicon Valley JUG: JVM Mechanics
 
Improving go-git performance
Improving go-git performanceImproving go-git performance
Improving go-git performance
 
Cocoa heads 09112017
Cocoa heads 09112017Cocoa heads 09112017
Cocoa heads 09112017
 
ClojureScript loves React, DomCode May 26 2015
ClojureScript loves React, DomCode May 26 2015ClojureScript loves React, DomCode May 26 2015
ClojureScript loves React, DomCode May 26 2015
 
The Ring programming language version 1.9 book - Part 9 of 210
The Ring programming language version 1.9 book - Part 9 of 210The Ring programming language version 1.9 book - Part 9 of 210
The Ring programming language version 1.9 book - Part 9 of 210
 
Presto anatomy
Presto anatomyPresto anatomy
Presto anatomy
 

More from Bo-Yi Wu

More from Bo-Yi Wu (20)

Drone CI/CD 自動化測試及部署
Drone CI/CD 自動化測試及部署Drone CI/CD 自動化測試及部署
Drone CI/CD 自動化測試及部署
 
Golang Project Layout and Practice
Golang Project Layout and PracticeGolang Project Layout and Practice
Golang Project Layout and Practice
 
Introduction to GitHub Actions
Introduction to GitHub ActionsIntroduction to GitHub Actions
Introduction to GitHub Actions
 
Drone 1.0 Feature
Drone 1.0 FeatureDrone 1.0 Feature
Drone 1.0 Feature
 
Drone CI/CD Platform
Drone CI/CD PlatformDrone CI/CD Platform
Drone CI/CD Platform
 
Go 語言基礎簡介
Go 語言基礎簡介Go 語言基礎簡介
Go 語言基礎簡介
 
drone continuous Integration
drone continuous Integrationdrone continuous Integration
drone continuous Integration
 
Gorush: A push notification server written in Go
Gorush: A push notification server written in GoGorush: A push notification server written in Go
Gorush: A push notification server written in Go
 
用 Drone 打造 輕量級容器持續交付平台
用 Drone 打造輕量級容器持續交付平台用 Drone 打造輕量級容器持續交付平台
用 Drone 打造 輕量級容器持續交付平台
 
用 Go 語言 打造微服務架構
用 Go 語言打造微服務架構用 Go 語言打造微服務架構
用 Go 語言 打造微服務架構
 
Introduction to Gitea with Drone
Introduction to Gitea with DroneIntroduction to Gitea with Drone
Introduction to Gitea with Drone
 
運用 Docker 整合 Laravel 提升團隊開發效率
運用 Docker 整合 Laravel 提升團隊開發效率運用 Docker 整合 Laravel 提升團隊開發效率
運用 Docker 整合 Laravel 提升團隊開發效率
 
用 Go 語言實戰 Push Notification 服務
用 Go 語言實戰 Push Notification 服務用 Go 語言實戰 Push Notification 服務
用 Go 語言實戰 Push Notification 服務
 
用 Go 語言打造 DevOps Bot
用 Go 語言打造 DevOps Bot用 Go 語言打造 DevOps Bot
用 Go 語言打造 DevOps Bot
 
A painless self-hosted Git service: Gitea
A painless self-hosted Git service: GiteaA painless self-hosted Git service: Gitea
A painless self-hosted Git service: Gitea
 
Write microservice in golang
Write microservice in golangWrite microservice in golang
Write microservice in golang
 
用 Docker 改善團隊合作模式
用 Docker 改善團隊合作模式用 Docker 改善團隊合作模式
用 Docker 改善團隊合作模式
 
Git flow 與團隊合作
Git flow 與團隊合作Git flow 與團隊合作
Git flow 與團隊合作
 
PHP & JavaScript & CSS Coding style
PHP & JavaScript & CSS Coding stylePHP & JavaScript & CSS Coding style
PHP & JavaScript & CSS Coding style
 
Docker 基礎介紹與實戰
Docker 基礎介紹與實戰Docker 基礎介紹與實戰
Docker 基礎介紹與實戰
 

Recently uploaded

Cloud Frontiers: A Deep Dive into Serverless Spatial Data and FME
Cloud Frontiers:  A Deep Dive into Serverless Spatial Data and FMECloud Frontiers:  A Deep Dive into Serverless Spatial Data and FME
Cloud Frontiers: A Deep Dive into Serverless Spatial Data and FME
Safe Software
 
Cloud Frontiers: A Deep Dive into Serverless Spatial Data and FME
Cloud Frontiers:  A Deep Dive into Serverless Spatial Data and FMECloud Frontiers:  A Deep Dive into Serverless Spatial Data and FME
Cloud Frontiers: A Deep Dive into Serverless Spatial Data and FME
Safe Software
 
Modular Monolith - a Practical Alternative to Microservices @ Devoxx UK 2024
Modular Monolith - a Practical Alternative to Microservices @ Devoxx UK 2024Modular Monolith - a Practical Alternative to Microservices @ Devoxx UK 2024
Modular Monolith - a Practical Alternative to Microservices @ Devoxx UK 2024
Victor Rentea
 

Recently uploaded (20)

Apidays New York 2024 - Accelerating FinTech Innovation by Vasa Krishnan, Fin...
Apidays New York 2024 - Accelerating FinTech Innovation by Vasa Krishnan, Fin...Apidays New York 2024 - Accelerating FinTech Innovation by Vasa Krishnan, Fin...
Apidays New York 2024 - Accelerating FinTech Innovation by Vasa Krishnan, Fin...
 
Web Form Automation for Bonterra Impact Management (fka Social Solutions Apri...
Web Form Automation for Bonterra Impact Management (fka Social Solutions Apri...Web Form Automation for Bonterra Impact Management (fka Social Solutions Apri...
Web Form Automation for Bonterra Impact Management (fka Social Solutions Apri...
 
Apidays New York 2024 - APIs in 2030: The Risk of Technological Sleepwalk by ...
Apidays New York 2024 - APIs in 2030: The Risk of Technological Sleepwalk by ...Apidays New York 2024 - APIs in 2030: The Risk of Technological Sleepwalk by ...
Apidays New York 2024 - APIs in 2030: The Risk of Technological Sleepwalk by ...
 
Cloud Frontiers: A Deep Dive into Serverless Spatial Data and FME
Cloud Frontiers:  A Deep Dive into Serverless Spatial Data and FMECloud Frontiers:  A Deep Dive into Serverless Spatial Data and FME
Cloud Frontiers: A Deep Dive into Serverless Spatial Data and FME
 
Strategies for Landing an Oracle DBA Job as a Fresher
Strategies for Landing an Oracle DBA Job as a FresherStrategies for Landing an Oracle DBA Job as a Fresher
Strategies for Landing an Oracle DBA Job as a Fresher
 
MINDCTI Revenue Release Quarter One 2024
MINDCTI Revenue Release Quarter One 2024MINDCTI Revenue Release Quarter One 2024
MINDCTI Revenue Release Quarter One 2024
 
Strategize a Smooth Tenant-to-tenant Migration and Copilot Takeoff
Strategize a Smooth Tenant-to-tenant Migration and Copilot TakeoffStrategize a Smooth Tenant-to-tenant Migration and Copilot Takeoff
Strategize a Smooth Tenant-to-tenant Migration and Copilot Takeoff
 
How to Troubleshoot Apps for the Modern Connected Worker
How to Troubleshoot Apps for the Modern Connected WorkerHow to Troubleshoot Apps for the Modern Connected Worker
How to Troubleshoot Apps for the Modern Connected Worker
 
Repurposing LNG terminals for Hydrogen Ammonia: Feasibility and Cost Saving
Repurposing LNG terminals for Hydrogen Ammonia: Feasibility and Cost SavingRepurposing LNG terminals for Hydrogen Ammonia: Feasibility and Cost Saving
Repurposing LNG terminals for Hydrogen Ammonia: Feasibility and Cost Saving
 
"I see eyes in my soup": How Delivery Hero implemented the safety system for ...
"I see eyes in my soup": How Delivery Hero implemented the safety system for ..."I see eyes in my soup": How Delivery Hero implemented the safety system for ...
"I see eyes in my soup": How Delivery Hero implemented the safety system for ...
 
ProductAnonymous-April2024-WinProductDiscovery-MelissaKlemke
ProductAnonymous-April2024-WinProductDiscovery-MelissaKlemkeProductAnonymous-April2024-WinProductDiscovery-MelissaKlemke
ProductAnonymous-April2024-WinProductDiscovery-MelissaKlemke
 
Apidays New York 2024 - Scaling API-first by Ian Reasor and Radu Cotescu, Adobe
Apidays New York 2024 - Scaling API-first by Ian Reasor and Radu Cotescu, AdobeApidays New York 2024 - Scaling API-first by Ian Reasor and Radu Cotescu, Adobe
Apidays New York 2024 - Scaling API-first by Ian Reasor and Radu Cotescu, Adobe
 
DBX First Quarter 2024 Investor Presentation
DBX First Quarter 2024 Investor PresentationDBX First Quarter 2024 Investor Presentation
DBX First Quarter 2024 Investor Presentation
 
Cloud Frontiers: A Deep Dive into Serverless Spatial Data and FME
Cloud Frontiers:  A Deep Dive into Serverless Spatial Data and FMECloud Frontiers:  A Deep Dive into Serverless Spatial Data and FME
Cloud Frontiers: A Deep Dive into Serverless Spatial Data and FME
 
DEV meet-up UiPath Document Understanding May 7 2024 Amsterdam
DEV meet-up UiPath Document Understanding May 7 2024 AmsterdamDEV meet-up UiPath Document Understanding May 7 2024 Amsterdam
DEV meet-up UiPath Document Understanding May 7 2024 Amsterdam
 
Navigating the Deluge_ Dubai Floods and the Resilience of Dubai International...
Navigating the Deluge_ Dubai Floods and the Resilience of Dubai International...Navigating the Deluge_ Dubai Floods and the Resilience of Dubai International...
Navigating the Deluge_ Dubai Floods and the Resilience of Dubai International...
 
Modular Monolith - a Practical Alternative to Microservices @ Devoxx UK 2024
Modular Monolith - a Practical Alternative to Microservices @ Devoxx UK 2024Modular Monolith - a Practical Alternative to Microservices @ Devoxx UK 2024
Modular Monolith - a Practical Alternative to Microservices @ Devoxx UK 2024
 
Artificial Intelligence Chap.5 : Uncertainty
Artificial Intelligence Chap.5 : UncertaintyArtificial Intelligence Chap.5 : Uncertainty
Artificial Intelligence Chap.5 : Uncertainty
 
Apidays New York 2024 - The value of a flexible API Management solution for O...
Apidays New York 2024 - The value of a flexible API Management solution for O...Apidays New York 2024 - The value of a flexible API Management solution for O...
Apidays New York 2024 - The value of a flexible API Management solution for O...
 
Connector Corner: Accelerate revenue generation using UiPath API-centric busi...
Connector Corner: Accelerate revenue generation using UiPath API-centric busi...Connector Corner: Accelerate revenue generation using UiPath API-centric busi...
Connector Corner: Accelerate revenue generation using UiPath API-centric busi...
 

用 Go 語言打造多台機器 Scale 架構