Created by Emily Gu / @CandySmurfy
https://candysmurf.github.io/GoReflectionTalk
Full Screen | F |
Next Slide | Space bar |
Slide Notes | S |
Thumbnail View | Esc |
View online at https://github.com/candysmurf/GoReflectionTalk
Note: Some slides move down instead of to the side, so use the space bar to advance slides.
I currently work for Intel Corporation as a cloud software engineer in the Software Defined Infrastructure (SDI-X) Emerging Tech group.
William Kennedy is my teacher for Go. His "mechanical sympathy" truly inspired me.
Prior to Go, I used Java, Spring Framework, RabbitMQ, Cassandra, Logstash, Elasticsearch...and worked on ECommerce, Big Data and Analytics.
{
"cluster_name": "elasticsearch",
"nodes": {
"jhO6RS8ORjOKfNP6pvwaBw": {
"timestamp": 1467525122508,
"name": "Superia",
"transport_address": "10.0.2.15:9300",
"host": "10.0.2.15",
"os": {
"timestamp": 1467525122530,
"cpu_percent": 30,
"load_average": 0.42,
"mem": {
"total_in_bytes": 1044631552,
"free_in_bytes": 65638400,
"used_in_bytes": 978993152,
"free_percent": 6,
"used_percent": 94
},
"swap": {
"total_in_bytes": 1211777024,
"free_in_bytes": 1199104000,
"used_in_bytes": 12673024
}
},
"process": {
"timestamp": 1467525122530,
"open_file_descriptors": 151,
"max_file_descriptors": 1048576,
"cpu": {
"percent": 4,
"total_in_millis": 5690
},
"mem": {
"total_virtual_in_bytes": 3219476480
}
},
"jvm": {
"timestamp": 1467525122530,
"uptime_in_millis": 42797,
"mem": {
"heap_used_in_bytes": 55298680,
"heap_used_percent": 5,
"heap_committed_in_bytes": 259719168,
"heap_max_in_bytes": 1065025536,
"non_heap_used_in_bytes": 44241384,
"non_heap_committed_in_bytes": 45834240,
"pools": {
"young": {
"used_in_bytes": 36094712,
"max_in_bytes": 69795840,
"peak_used_in_bytes": 69795840,
"peak_max_in_bytes": 69795840
},
"survivor": {
"used_in_bytes": 8716280,
"max_in_bytes": 8716288,
"peak_used_in_bytes": 8716280,
"peak_max_in_bytes": 8716288
},
"old": {
"used_in_bytes": 10487688,
"max_in_bytes": 986513408,
"peak_used_in_bytes": 10487688,
"peak_max_in_bytes": 986513408
}
}
},
"threads": {
"count": 33,
"peak_count": 36
},
"gc": {
"collectors": {
"young": {
"collection_count": 4,
"collection_time_in_millis": 76
},
"old": {
"collection_count": 1,
"collection_time_in_millis": 16
}
}
},
"buffer_pools": {
"direct": {
"count": 13,
"used_in_bytes": 3022957,
"total_capacity_in_bytes": 3022957
},
"mapped": {
"count": 0,
"used_in_bytes": 0,
"total_capacity_in_bytes": 0
}
},
"classes": {
"current_loaded_count": 6603,
"total_loaded_count": 6603,
"total_unloaded_count": 0
}
}
}
}
/intel/es/node/*/mem/heap_used_in_bytes 55298680
/intel/es/node/*/mem/heap_max_in_bytes 1065025536
/intel/es/node/*/jvm/mem/pools/young/used_in_bytes 36094712
/intel/es/node/*/jvm/mem/pools/survivor/used_in_bytes 8716280
/intel/es/node/*/jvm/mem/pools/old/used_in_bytes 10487688
/intel/es/node/*/os/swap/total_in_bytes 1211777024
/intel/es/node/*/fs/data/total_in_bytes 19507089408
Reflection in computing is the ability of a program to examine its own structure, particularly through types; it's a form of metaprogramming.
— Rob Pike at The Laws of Reflection
It's a powerful tool that should be used with care and avoided unless strictly necessary.
— Rob Pike at The Laws of Reflection
" Compared to a disk seek or network transfer, the cost of reflection will be negligible."
— Dave Cheney
" Integrity, Readability, Simplicity first! "
— William Kennedy
func MultiplyBy2(x int) int {
return x * 2
}
func FastMultiplyBy2(x int) int {
return x << 1
}
"Premature Optimizations and Programming Myths are The Root of all Evil"
— Alvaro Videla 2015
Without Reflection, you'll have to write different code for every type when doing data transformation or resource injection.
"fmt"
"encoding/json"
"encoding/xml"
"text/template"
"html/template"
Go Reflection package provides robust operations on kinds and values during the run-time.
Readability and Simplicity
Integrity
Redfish API |
"DMTF’s Redfish™ is an open industry standard specification and schema that specifies a RESTful interface and utilizes JSON and OData to help customers integrate solutions within their existing tool chains."
— redfish.dmtf.org
/intel/redfish/v1/Systems/*/Processors/*/TotalCores |
/intel/redfish/v1/Systems/*/ProcessorSummary/Count |
/intel/redfish/v1/Chassis/*/Thermal/Temperatures/*/UpperThresholdNonCritical |
/intel/redfish/v1/Chassis/*/Thermal/Temperatures/*/MinReadingRange |
/intel/redfish/v1/Chassis/*/Thermal/Temperatures/*/UpperThresholdFatal |
Reflection: | Code |
// traversal goes through all reachable pages and builds up the metrics
func (rc *redfishClient) traversal(uri string, data map[string]interface{}) error {
for k, v := range data {
// skips the null value
typ := reflect.TypeOf(v)
if typ == nil {
continue
}
switch typ.Kind() {
case reflect.String:
rc.AllPoints = append(rc.AllPoints, plugin.MetricType{
Namespace_: core.NewNamespace(strings.Split(Intel+uri+Slash+k, Slash)...),
Data_: v,
Unit_: typ.Kind().String(),
Timestamp_: time.Now(),
})
if k == APIKey {
val := reflect.ValueOf(v).String()
if _, ok := rc.visitedURIs[val]; !ok {
err := rc.drilldownMetricData(val)
if err != nil {
return err
}
}
}
case reflect.Slice:
s := reflect.ValueOf(v)
for i := 0; i < s.Len(); i++ {
switch reflect.TypeOf(s.Index(i)).Kind() {
case reflect.Struct:
if s.Index(i).Elem().Kind() == reflect.Map {
rc.traversal(uri+Slash+k+Slash+strconv.Itoa(i), s.Index(i).Interface().(map[string]interface{}))
} else {
rc.AllPoints = append(rc.AllPoints, plugin.MetricType{
Namespace_: core.NewNamespace(strings.Split(Intel+uri+Slash+k+Slash+strconv.Itoa(i), Slash)...),
Data_: s.Index(i).Interface(),
Unit_: typ.Kind().String(),
Timestamp_: time.Now(),
})
}
default:
redfishLogger.WithFields(log.Fields{
"_block": "traversal",
"key": k,
"data": v,
"type": s.Index(i).Type().Kind(),
}).Info("redfish client traversals reachable data points")
}
}
case reflect.Map:
rc.traversal(uri+"/"+k, v.(map[string]interface{}))
default:
rc.AllPoints = append(rc.AllPoints, plugin.MetricType{
Namespace_: core.NewNamespace(strings.Split(Intel+uri+Slash+k, Slash)...),
Data_: v,
Unit_: typ.Kind().String(),
Timestamp_: time.Now(),
})
}
}
return nil
}