Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Developing Your Own Flux Packages (InfluxDays London 2019)

Developing Your Own Flux Packages (InfluxDays London 2019)

Flux is easy to contribute to, and it is easy to share functions and libraries of Flux code with other developers. Although there are many functions in the language, the true power of Flux is its ability to be extended with custom functions. In this session, David will show you how to write your own custom function to perform some new analytics.

69172dc4e4cc3e4cdd234c40adf395fa?s=128

David McKay

June 14, 2019
Tweet

Transcript

  1. None
  2. None
  3. ★ ★ ★ ★

  4. None
  5. // This is a comment

  6. name = “David McKay” age = 1.2 alive = true

  7. name = “David McKay” objects = {name, age: 23}

  8. durationLiteral = 1mo7d timeLiterals = 2018-08-28T10:20:00Z = 2018-08-28 dateMath =

    2019-01-01 + 1mo3d
  9. square = (n) => n * n tweet(at: “rawkode”, message:

    “Sweet!”)
  10. moveIn() |> moveOut() |> handsUp() |> handsDown() |> backUp() |>

    backUp() |> roll()
  11. > ʭ = () => "I don't know what this

    symbol is called" > ʭ () -> string > ʭ() I don't know what this symbol is called
  12. > hotdog = () => “Armour !” > hotdog() >

    Armour ! > = () => “Armour Hotdog!” Error: invalid statement @1:1-1:5:
  13. None
  14. package rawkode gitHubHandle = “rawkode” hello = () => "Hello"

    awesomeThings = ["BBQ", "Hot Sauce", “”]
  15. package rawkode awesomeise = (table=<-) => { table |> map(fn:

    (r) => "Awesome" + r) }
  16. rawkode@penguin:~ ./flux repl > @rawkode.flux > awesomeThings |> awesomeise

  17. None
  18. None
  19. ➔ ➔ ➔ ➔ ➔ ➔ ➔ ➔

  20. import "math" math.NaN() // Returns NaN

  21. import "math" math.sqrt(x: 4.0) // Returns 2.0

  22. import "strings" strings.title(v: "a flux of foxes") // returns "A

    Flux Of Foxes"
  23. import "csv" csv.from(file: "/path/to/data-file.csv") // OR csv.from(csv: csvData)

  24. import "testing" testing.assertEquals( name: "streamEquality", got: got, want: want )

  25. None
  26. ★ ★ ◦ ◦ ◦ ◦ ★

  27. ★ ★ ★

  28. None
  29. None
  30. package math // builtin constants builtin pi // builtin functions

    builtin abs
  31. package math func init() { // constants flux.RegisterPackageValue("math", "pi", values.NewFloat(math.Pi))

    }
  32. None
  33. "github.com/influxdata/flux/values"

  34. package math func init() { // constants flux.RegisterPackageValue("math", "pi", values.NewFloat(math.Pi))

    }
  35. package math func init() { // rand function flux.RegisterPackageValue( values.NewFunction(“math”,

    ???) ) }
  36. ★ ◦ ◦ ◦ ◦

  37. values.NewFunction( "rand", ???, ???, ??? )

  38. // rand with no params semantic.NewFunctionPolyType(semantic.FunctionPolySignature{ Parameters: map[string]semantic.PolyType{}, Return: semantic.UInt,

    }), // in Go: func rand() uint
  39. // rand with 1 param: max semantic.NewFunctionPolyType(semantic.FunctionPolySignature{ Parameters: map[string]semantic.PolyType{ "max":

    semantic.UInt }, Required: semantic.LabelSet{"max"}, Return: semantic.UInt, }), // in Go: func rand(max uint) uint
  40. // rand with 2 param: min, max semantic.NewFunctionPolyType(semantic.FunctionPolySignature{ Parameters: map[string]semantic.PolyType{

    "min": semantic.UInt, "max": semantic.UInt }, Required: semantic.LabelSet{"min", "max"}, Return: semantic.UInt, }), // in Go: func rand(min uint, max uint) uint
  41. values.NewFunction( "rand", semantic.NewFunctionPolyType( … ) ???, ??? )

  42. // No Error Checking func() (values.Value, error) { goRand :=

    rand.New(rand.NewSource(...)) return values.NewFloat(goRand.Intn(100)), nil }
  43. func(args values.Object) (values.Value, error) { max, ok := args.Get("max") if

    !ok { return nil, errors.New("missing argument max") } if max.Type().Nature() == semantic.UInt { goRand := rand.New(rand.NewSource(time.Now().UnixNano())) return values.NewFloat(goRand.Intn(max.UInt())), nil } return nil, fmt.Errorf( "cannot convert argument of type %v to uint", v.Type().Nature() ) }
  44. values.NewFunction( "rand", semantic.NewFunctionPolyType( … ) func(args values.Object) (values.Value, error){ …

    }, ??? )
  45. None
  46. values.NewFunction( "rand", semantic.NewFunctionPolyType( … ) func(args values.Object) (values.Value, error){ …

    }, false )
  47. None
  48. Compilation !== Unit Test

  49. expected = goRand.Intn(100)

  50. fluxFn = values.NewFunction(...) fluxArg := values.NewObjectWithValues( map[string]values.Value{ "max": values.NewFloat(100) }

    ) result, err := fluxFn.Call(fluxArg)
  51. None
  52. None
  53. None
  54. None
  55. None
  56. None
  57. None
  58. None
  59. None
  60. None
  61. None
  62. None
  63. 1. 2. 3.

  64. None
  65. Thank You