<commit_before>// This file was auto-generated via go generate.
// DO NOT UPDATE MANUALLY

/*
The v23 tool helps manage vanadium development.

Usage:
   v23 [flags] <command>

The v23 commands are:
   buildcop     Manage vanadium build cop schedule
   contributors List vanadium project contributors
   env          Print vanadium environment variables
   go           Execute the go tool using the vanadium environment
   goext        Vanadium extensions of the go tool
   profile      Manage vanadium profiles
   project      Manage the vanadium projects
   run          Run an executable using the vanadium environment
   snapshot     Manage snapshots of the vanadium project
   test         Manage vanadium tests
   update       Update all vanadium tools and projects
   version      Print version
   xgo          Execute the go tool using the vanadium environment and
                cross-compilation
   help         Display help for commands or topics
Run "v23 help [command]" for command usage.

The v23 flags are:
 -n=false
   Show what commands will run but do not execute them.
 -nocolor=false
   Do not use color to format output.
 -v=false
   Print verbose output.

V23 Buildcop

Manage vanadium build cop schedule. If no subcommand is given, it shows the LDAP
of the current build cop.

Usage:
   v23 buildcop <command>
   v23 buildcop

The v23 buildcop commands are:
   list        List available build cop schedule

V23 Buildcop List

List available build cop schedule.

Usage:
   v23 buildcop list

V23 Contributors

Lists vanadium project contributors and the number of their commits. Vanadium
projects to consider can be specified as an argument. If no projects are
specified, all vanadium projects are considered by default.

Usage:
   v23 contributors <projects>

<projects> is a list of projects to consider.

V23 Env

Print vanadium environment variables.

If no arguments are given, prints all variables in NAME="VALUE" format, each on
a separate line ordered by name.  This format makes it easy to set all vars by
running the following bash command (or similar for other shells):
   eval $(v23 env)

If arguments are given, prints only the value of each named variable, each on a
separate line in the same order as the arguments.

Usage:
   v23 env [flags] [name ...]

[name ...] is an optional list of variable names.

The v23 env flags are:
 -platform=
   Target platform.

V23 Go

Wrapper around the 'go' tool that can be used for compilation of vanadium Go
sources. It takes care of vanadium-specific setup, such as setting up the Go
specific environment variables or making sure that VDL generated files are
regenerated before compilation.

In particular, the tool invokes the following command before invoking any go
tool commands that compile vanadium Go code:

vdl generate -lang=go all

Usage:
   v23 go [flags] <arg ...>

<arg ...> is a list of arguments for the go tool.

The v23 go flags are:
 -host_go=go
   Go command for the host platform.
 -target_go=go
   Go command for the target platform.

V23 Goext

Vanadium extension of the go tool.

Usage:
   v23 goext <command>

The v23 goext commands are:
   distclean   Restore the vanadium Go workspaces to their pristine state

V23 Goext Distclean

Unlike the 'go clean' command, which only removes object files for packages in
the source tree, the 'goext disclean' command removes all object files from
vanadium Go workspaces. This functionality is needed to avoid accidental use of
stale object files that correspond to packages that no longer exist in the
source tree.

Usage:
   v23 goext distclean

V23 Profile

To facilitate development across different platforms, vanadium defines
platform-independent profiles that map different platforms to a set of libraries
and tools that can be used for a factor of vanadium development.

Usage:
   v23 profile <command>

The v23 profile commands are:
   list        List known vanadium profiles
   setup       Set up the given vanadium profiles

V23 Profile List

List known vanadium profiles.

Usage:
   v23 profile list

V23 Profile Setup

Set up the given vanadium profiles.

Usage:
   v23 profile setup <profiles>

<profiles> is a list of profiles to set up.

V23 Project

Manage the vanadium projects.

Usage:
   v23 project [flags] <command>

The v23 project commands are:
   list         List existing vanadium projects and branches
   shell-prompt Print a succinct status of projects, suitable for shell prompts
   poll         Poll existing vanadium projects

The v23 project flags are:
 -manifest=default
   Name of the project manifest.

V23 Project List

Inspect the local filesystem and list the existing projects and branches.

Usage:
   v23 project list [flags]

The v23 project list flags are:
 -branches=false
   Show project branches.
 -nopristine=false
   If true, omit pristine projects, i.e. projects with a clean master branch and
   no other branches.

V23 Project Shell-Prompt

Reports current branches of vanadium projects (repositories) as well as an
indication of each project's status:
  *  indicates that a repository contains uncommitted changes
  %  indicates that a repository contains untracked files

Usage:
   v23 project shell-prompt [flags]

The v23 project shell-prompt flags are:
 -check_dirty=true
   If false, don't check for uncommitted changes or untracked files. Setting
   this option to false is dangerous: dirty master branches will not appear in
   the output.
 -show_current_repo_name=false
   Show the name of the current repo.

V23 Project Poll

Poll vanadium projects that can affect the outcome of the given tests and report
whether any new changes in these projects exist. If no tests are specified, all
projects are polled by default.

Usage:
   v23 project poll <test ...>

<test ...> is a list of tests that determine what projects to poll.

V23 Run

Run an executable using the vanadium environment.

Usage:
   v23 run <executable> [arg ...]

<executable> [arg ...] is the executable to run and any arguments to pass
verbatim to the executable.

V23 Snapshot

The "v23 snapshot" command can be used to manage snapshots of the vanadium
project. In particular, it can be used to create new snapshots and to list
existing snapshots.

The command-line flag "-remote" determines whether the command pertains to
"local" snapshots that are only stored locally or "remote" snapshots the are
revisioned in the manifest repository.

Usage:
   v23 snapshot [flags] <command>

The v23 snapshot commands are:
   create      Create a new snapshot of the vanadium project
   list        List existing snapshots of vanadium projects

The v23 snapshot flags are:
 -remote=false
   Manage remote snapshots.

V23 Snapshot Create

The "v23 snapshot create <label>" command first checks whether the vanadium
project configuration associates the given label with any tests. If so, the
command checks that all of these tests pass.

Next, the command captures the current state of the vanadium project as a
manifest and, depending on the value of the -remote flag, the command either
stores the manifest in the local $VANADIUM_ROOT/.snapshots directory, or in the
manifest repository, pushing the change to the remote repository and thus making
it available globally.

Internally, snapshots are organized as follows:

 <snapshot-dir>/
   labels/
     <label1>/
       <label1-snapshot1>
       <label1-snapshot2>
       ...
     <label2>/
       <label2-snapshot1>
       <label2-snapshot2>
       ...
     <label3>/
     ...
   <label1> # a symlink to the latest <label1-snapshot*>
   <label2> # a symlink to the latest <label2-snapshot*>
   ...

NOTE: Unlike the v23 tool commands, the above internal organization is not an
API. It is an implementation and can change without notice.

Usage:
   v23 snapshot create <label>

<label> is the snapshot label.

V23 Snapshot List

The "snapshot list" command lists existing snapshots of the labels specified as
command-line arguments. If no arguments are provided, the command lists
snapshots for all known labels.

Usage:
   v23 snapshot list <label ...>

<label ...> is a list of snapshot labels.

V23 Test

Manage vanadium tests.

Usage:
   v23 test <command>

The v23 test commands are:
   project     Run tests for a vanadium project
   run         Run vanadium tests
   list        List vanadium tests

V23 Test Project

Runs tests for a vanadium project that is by the remote URL specified as the
command-line argument. Projects hosted on googlesource.com, can be specified
using the basename of the URL (e.g. "vanadium.go.core" implies
"https://vanadium.googlesource.com/vanadium.go.core").

Usage:
   v23 test project <project>

<project> identifies the project for which to run tests.

V23 Test Run

Run vanadium tests.

Usage:
   v23 test run <name ...>

<name ...> is a list names identifying the tests to run.

V23 Test List

List vanadium tests.

Usage:
   v23 test list

V23 Update

Updates all vanadium projects, builds the latest version of vanadium tools, and
installs the resulting binaries into $VANADIUM_ROOT/bin. The sequence in which
the individual updates happen guarantees that we end up with a consistent set of
tools and source code.

The set of project and tools to update is describe by a manifest. Vanadium
manifests are revisioned and stored in a "manifest" repository, that is
available locally in $VANADIUM_ROOT/.manifest. The manifest uses the following
XML schema:

 <manifest>
   <imports>
     <import name="default"/>
     ...
   </imports>
   <projects>
     <project name="https://vanadium.googlesource.com/vanadium.go.core"
              path="release/go/src/v.io/veyron"
              protocol="git"
              revision="HEAD"/>
     ...
   </projects>
   <tools>
     <tool name="v23" package="v.io/tools/v23"/>
     ...
   </tools>
 </manifest>

The <import> element can be used to share settings across multiple manifests.
Import names are interpreted relative to the $VANADIUM_ROOT/.manifest/v1
directory. Import cycles are not allowed and if a project or a tool is specified
multiple times, the last specification takes effect. In particular, the elements
<project name="foo" exclude="true"/> and <tool name="bar" exclude="true"/> can
be used to exclude previously included projects and tools.

The tool identifies which manifest to use using the following algorithm. If the
$VANADIUM_ROOT/.local_manifest file exists, then it is used. Otherwise, the
$VANADIUM_ROOT/.manifest/v1/<manifest>.xml file is used, which <manifest> is the
value of the -manifest command-line flag, which defaults to "default".

NOTE: Unlike the v23 tool commands, the above manifest file format is not an
API. It is an implementation and can change without notice.

Usage:
   v23 update [flags]

The v23 update flags are:
 -gc=false
   Garbage collect obsolete repositories.
 -manifest=default
   Name of the project manifest.

V23 Version

Print version of the v23 tool.

Usage:
   v23 version

V23 Xgo

Wrapper around the 'go' tool that can be used for cross-compilation of vanadium
Go sources. It takes care of vanadium-specific setup, such as setting up the Go
specific environment variables or making sure that VDL generated files are
regenerated before compilation.

In particular, the tool invokes the following command before invoking any go
tool commands that compile vanadium Go code:

vdl generate -lang=go all

Usage:
   v23 xgo [flags] <platform> <arg ...>

<platform> is the cross-compilation target and has the general format
<arch><sub>-<os> or <arch><sub>-<os>-<env> where: - <arch> is the platform
architecture (e.g. 386, amd64 or arm) - <sub> is the platform sub-architecture
(e.g. v6 or v7 for arm) - <os> is the platform operating system (e.g. linux or
darwin) - <env> is the platform environment (e.g. gnu or android)

<arg ...> is a list of arguments for the go tool."

The v23 xgo flags are:
 -host_go=go
   Go command for the host platform.
 -target_go=go
   Go command for the target platform.

V23 Help

Help with no args displays the usage of the parent command.

Help with args displays the usage of the specified sub-command or help topic.

"help ..." recursively displays help for all commands and topics.

The output is formatted to a target width in runes.  The target width is
determined by checking the environment variable CMDLINE_WIDTH, falling back on
the terminal width from the OS, falling back on 80 chars.  By setting
CMDLINE_WIDTH=x, if x > 0 the width is x, if x < 0 the width is unlimited, and
if x == 0 or is unset one of the fallbacks is used.

Usage:
   v23 help [flags] [command/topic ...]

[command/topic ...] optionally identifies a specific sub-command or help topic.

The v23 help flags are:
 -style=text
   The formatting style for help output, either "text" or "godoc".
*/
package main
<commit_msg>Post-migration cleanup.<commit_after>// This file was auto-generated via go generate.
// DO NOT UPDATE MANUALLY

/*
The v23 tool helps manage vanadium development.

Usage:
   v23 [flags] <command>

The v23 commands are:
   buildcop     Manage vanadium build cop schedule
   contributors List vanadium project contributors
   env          Print vanadium environment variables
   go           Execute the go tool using the vanadium environment
   goext        Vanadium extensions of the go tool
   profile      Manage vanadium profiles
   project      Manage the vanadium projects
   run          Run an executable using the vanadium environment
   snapshot     Manage snapshots of the vanadium project
   test         Manage vanadium tests
   update       Update all vanadium tools and projects
   version      Print version
   xgo          Execute the go tool using the vanadium environment and
                cross-compilation
   help         Display help for commands or topics
Run "v23 help [command]" for command usage.

The v23 flags are:
 -n=false
   Show what commands will run but do not execute them.
 -nocolor=false
   Do not use color to format output.
 -v=false
   Print verbose output.

V23 Buildcop

Manage vanadium build cop schedule. If no subcommand is given, it shows the LDAP
of the current build cop.

Usage:
   v23 buildcop <command>
   v23 buildcop

The v23 buildcop commands are:
   list        List available build cop schedule

V23 Buildcop List

List available build cop schedule.

Usage:
   v23 buildcop list

V23 Contributors

Lists vanadium project contributors and the number of their commits. Vanadium
projects to consider can be specified as an argument. If no projects are
specified, all vanadium projects are considered by default.

Usage:
   v23 contributors <projects>

<projects> is a list of projects to consider.

V23 Env

Print vanadium environment variables.

If no arguments are given, prints all variables in NAME="VALUE" format, each on
a separate line ordered by name.  This format makes it easy to set all vars by
running the following bash command (or similar for other shells):
   eval $(v23 env)

If arguments are given, prints only the value of each named variable, each on a
separate line in the same order as the arguments.

Usage:
   v23 env [flags] [name ...]

[name ...] is an optional list of variable names.

The v23 env flags are:
 -platform=
   Target platform.

V23 Go

Wrapper around the 'go' tool that can be used for compilation of vanadium Go
sources. It takes care of vanadium-specific setup, such as setting up the Go
specific environment variables or making sure that VDL generated files are
regenerated before compilation.

In particular, the tool invokes the following command before invoking any go
tool commands that compile vanadium Go code:

vdl generate -lang=go all

Usage:
   v23 go [flags] <arg ...>

<arg ...> is a list of arguments for the go tool.

The v23 go flags are:
 -host_go=go
   Go command for the host platform.
 -target_go=go
   Go command for the target platform.

V23 Goext

Vanadium extension of the go tool.

Usage:
   v23 goext <command>

The v23 goext commands are:
   distclean   Restore the vanadium Go workspaces to their pristine state

V23 Goext Distclean

Unlike the 'go clean' command, which only removes object files for packages in
the source tree, the 'goext disclean' command removes all object files from
vanadium Go workspaces. This functionality is needed to avoid accidental use of
stale object files that correspond to packages that no longer exist in the
source tree.

Usage:
   v23 goext distclean

V23 Profile

To facilitate development across different platforms, vanadium defines
platform-independent profiles that map different platforms to a set of libraries
and tools that can be used for a factor of vanadium development.

Usage:
   v23 profile <command>

The v23 profile commands are:
   list        List known vanadium profiles
   setup       Set up the given vanadium profiles

V23 Profile List

List known vanadium profiles.

Usage:
   v23 profile list

V23 Profile Setup

Set up the given vanadium profiles.

Usage:
   v23 profile setup <profiles>

<profiles> is a list of profiles to set up.

V23 Project

Manage the vanadium projects.

Usage:
   v23 project [flags] <command>

The v23 project commands are:
   list         List existing vanadium projects and branches
   shell-prompt Print a succinct status of projects, suitable for shell prompts
   poll         Poll existing vanadium projects

The v23 project flags are:
 -manifest=default
   Name of the project manifest.

V23 Project List

Inspect the local filesystem and list the existing projects and branches.

Usage:
   v23 project list [flags]

The v23 project list flags are:
 -branches=false
   Show project branches.
 -nopristine=false
   If true, omit pristine projects, i.e. projects with a clean master branch and
   no other branches.

V23 Project Shell-Prompt

Reports current branches of vanadium projects (repositories) as well as an
indication of each project's status:
  *  indicates that a repository contains uncommitted changes
  %  indicates that a repository contains untracked files

Usage:
   v23 project shell-prompt [flags]

The v23 project shell-prompt flags are:
 -check_dirty=true
   If false, don't check for uncommitted changes or untracked files. Setting
   this option to false is dangerous: dirty master branches will not appear in
   the output.
 -show_current_repo_name=false
   Show the name of the current repo.

V23 Project Poll

Poll vanadium projects that can affect the outcome of the given tests and report
whether any new changes in these projects exist. If no tests are specified, all
projects are polled by default.

Usage:
   v23 project poll <test ...>

<test ...> is a list of tests that determine what projects to poll.

V23 Run

Run an executable using the vanadium environment.

Usage:
   v23 run <executable> [arg ...]

<executable> [arg ...] is the executable to run and any arguments to pass
verbatim to the executable.

V23 Snapshot

The "v23 snapshot" command can be used to manage snapshots of the vanadium
project. In particular, it can be used to create new snapshots and to list
existing snapshots.

The command-line flag "-remote" determines whether the command pertains to
"local" snapshots that are only stored locally or "remote" snapshots the are
revisioned in the manifest repository.

Usage:
   v23 snapshot [flags] <command>

The v23 snapshot commands are:
   create      Create a new snapshot of the vanadium project
   list        List existing snapshots of vanadium projects

The v23 snapshot flags are:
 -remote=false
   Manage remote snapshots.

V23 Snapshot Create

The "v23 snapshot create <label>" command first checks whether the vanadium
project configuration associates the given label with any tests. If so, the
command checks that all of these tests pass.

Next, the command captures the current state of the vanadium project as a
manifest and, depending on the value of the -remote flag, the command either
stores the manifest in the local $VANADIUM_ROOT/.snapshots directory, or in the
manifest repository, pushing the change to the remote repository and thus making
it available globally.

Internally, snapshots are organized as follows:

 <snapshot-dir>/
   labels/
     <label1>/
       <label1-snapshot1>
       <label1-snapshot2>
       ...
     <label2>/
       <label2-snapshot1>
       <label2-snapshot2>
       ...
     <label3>/
     ...
   <label1> # a symlink to the latest <label1-snapshot*>
   <label2> # a symlink to the latest <label2-snapshot*>
   ...

NOTE: Unlike the v23 tool commands, the above internal organization is not an
API. It is an implementation and can change without notice.

Usage:
   v23 snapshot create <label>

<label> is the snapshot label.

V23 Snapshot List

The "snapshot list" command lists existing snapshots of the labels specified as
command-line arguments. If no arguments are provided, the command lists
snapshots for all known labels.

Usage:
   v23 snapshot list <label ...>

<label ...> is a list of snapshot labels.

V23 Test

Manage vanadium tests.

Usage:
   v23 test <command>

The v23 test commands are:
   project     Run tests for a vanadium project
   run         Run vanadium tests
   list        List vanadium tests

V23 Test Project

Runs tests for a vanadium project that is by the remote URL specified as the
command-line argument. Projects hosted on googlesource.com, can be specified
using the basename of the URL (e.g. "vanadium.go.core" implies
"https://vanadium.googlesource.com/vanadium.go.core").

Usage:
   v23 test project <project>

<project> identifies the project for which to run tests.

V23 Test Run

Run vanadium tests.

Usage:
   v23 test run <name ...>

<name ...> is a list names identifying the tests to run.

V23 Test List

List vanadium tests.

Usage:
   v23 test list

V23 Update

Updates all vanadium projects, builds the latest version of vanadium tools, and
installs the resulting binaries into $VANADIUM_ROOT/bin. The sequence in which
the individual updates happen guarantees that we end up with a consistent set of
tools and source code.

The set of project and tools to update is describe by a manifest. Vanadium
manifests are revisioned and stored in a "manifest" repository, that is
available locally in $VANADIUM_ROOT/.manifest. The manifest uses the following
XML schema:

 <manifest>
   <imports>
     <import name="default"/>
     ...
   </imports>
   <projects>
     <project name="https://vanadium.googlesource.com/vanadium.go.core"
              path="release/go/src/v.io/core"
              protocol="git"
              revision="HEAD"/>
     ...
   </projects>
   <tools>
     <tool name="v23" package="v.io/tools/v23"/>
     ...
   </tools>
 </manifest>

The <import> element can be used to share settings across multiple manifests.
Import names are interpreted relative to the $VANADIUM_ROOT/.manifest/v1
directory. Import cycles are not allowed and if a project or a tool is specified
multiple times, the last specification takes effect. In particular, the elements
<project name="foo" exclude="true"/> and <tool name="bar" exclude="true"/> can
be used to exclude previously included projects and tools.

The tool identifies which manifest to use using the following algorithm. If the
$VANADIUM_ROOT/.local_manifest file exists, then it is used. Otherwise, the
$VANADIUM_ROOT/.manifest/v1/<manifest>.xml file is used, which <manifest> is the
value of the -manifest command-line flag, which defaults to "default".

NOTE: Unlike the v23 tool commands, the above manifest file format is not an
API. It is an implementation and can change without notice.

Usage:
   v23 update [flags]

The v23 update flags are:
 -gc=false
   Garbage collect obsolete repositories.
 -manifest=default
   Name of the project manifest.

V23 Version

Print version of the v23 tool.

Usage:
   v23 version

V23 Xgo

Wrapper around the 'go' tool that can be used for cross-compilation of vanadium
Go sources. It takes care of vanadium-specific setup, such as setting up the Go
specific environment variables or making sure that VDL generated files are
regenerated before compilation.

In particular, the tool invokes the following command before invoking any go
tool commands that compile vanadium Go code:

vdl generate -lang=go all

Usage:
   v23 xgo [flags] <platform> <arg ...>

<platform> is the cross-compilation target and has the general format
<arch><sub>-<os> or <arch><sub>-<os>-<env> where: - <arch> is the platform
architecture (e.g. 386, amd64 or arm) - <sub> is the platform sub-architecture
(e.g. v6 or v7 for arm) - <os> is the platform operating system (e.g. linux or
darwin) - <env> is the platform environment (e.g. gnu or android)

<arg ...> is a list of arguments for the go tool."

The v23 xgo flags are:
 -host_go=go
   Go command for the host platform.
 -target_go=go
   Go command for the target platform.

V23 Help

Help with no args displays the usage of the parent command.

Help with args displays the usage of the specified sub-command or help topic.

"help ..." recursively displays help for all commands and topics.

The output is formatted to a target width in runes.  The target width is
determined by checking the environment variable CMDLINE_WIDTH, falling back on
the terminal width from the OS, falling back on 80 chars.  By setting
CMDLINE_WIDTH=x, if x > 0 the width is x, if x < 0 the width is unlimited, and
if x == 0 or is unset one of the fallbacks is used.

Usage:
   v23 help [flags] [command/topic ...]

[command/topic ...] optionally identifies a specific sub-command or help topic.

The v23 help flags are:
 -style=text
   The formatting style for help output, either "text" or "godoc".
*/
package main
<|endoftext|>


<commit_before>package valente

import (
	"log"

	"golang.org/x/net/websocket"
)

//HandlerFunc is a function of handle an event received into websocket.Conn
type HandlerFunc func(*websocket.Conn, *App)

//Form represents the unit of user interaction
type Form interface {
	AddEventHandler(evt string, f HandlerFunc) Form
	Run(ws *websocket.Conn, app *App) error
	Initialize(ws *websocket.Conn) Form
	App() *App
	SetApp(app *App)
}

//FormImpl its a simple Form
type FormImpl struct {
	trans map[string]HandlerFunc
	app   *App
}

//App return the app reference
func (form FormImpl) App() *App {
	return form.app
}

//SetApp set the app reference
func (form FormImpl) SetApp(a *App) {
	form.app = a
}

//AddEventHandler add an f function to handle evt event
func (form FormImpl) AddEventHandler(evt string, f HandlerFunc) Form {
	if form.trans == nil {
		form.trans = map[string]HandlerFunc{}
	}
	form.trans[evt] = f
	return form
}

//Run execs the form
func (form FormImpl) Run(ws *websocket.Conn, app *App) error {
	msg := ""
	err := websocket.Message.Receive(ws, &msg)
	if err != nil {
		log.Println("Error on WS Receive", err)
		return err
	}
	println(msg, form.trans)
	f, present := form.trans[msg]
	if present {
		f(ws, app)
	} else {
		log.Println("Evt not found", msg)
	}
	return nil
}

//Initialize inits the form
func (form FormImpl) Initialize(ws *websocket.Conn) Form {
	log.Println("FormImpl Initialize")
	return form
}

//App is a Web Application representation
type App struct {
	WS          *websocket.Conn
	Forms       map[string]Form
	Data        map[string]interface{}
	CurrentForm Form
}

//GoTo replace the current form into app
func (app *App) GoTo(formName string) error {
	log.Println("App goto", formName)
	form, present := app.Forms[formName]
	if present {
		app.CurrentForm = form.Initialize(app.WS)
	} else {
		log.Println("[ERROR] Form not registred", formName)
	}
	return nil
}

//Run handle events
func (app *App) Run() {
	app.Data = map[string]interface{}{}
	for {
		err := app.CurrentForm.Run(app.WS, app)
		if err != nil {
			return
		}
	}
}

//Initialize inits the App
func (app *App) Initialize() {
	log.Println("App Initialize")
}

//AddForm add a new form to App
func (app *App) AddForm(name string, f Form) {
	if app.Forms == nil {
		app.Forms = map[string]Form{}
	}

	f.SetApp(app)
	app.Forms[name] = f
}
<commit_msg>experiment<commit_after>package valente

import (
	"log"

	"golang.org/x/net/websocket"
)

//HandlerFunc is a function of handle an event received into websocket.Conn
type HandlerFunc func(*websocket.Conn, *App)

//Form represents the unit of user interaction
type Form interface {
	AddEventHandler(evt string, f HandlerFunc) Form
	Run(ws *websocket.Conn, app *App) error
	Initialize(ws *websocket.Conn) Form
	App() *App
	SetApp(app *App)
}

//FormImpl its a simple Form
type FormImpl struct {
	trans  map[string]HandlerFunc
	RefApp *App
}

//App return the app reference
func (form FormImpl) App() *App {
	return form.RefApp
}

//SetApp set the app reference
func (form FormImpl) SetApp(a *App) {
	form.RefApp = a
}

//AddEventHandler add an f function to handle evt event
func (form FormImpl) AddEventHandler(evt string, f HandlerFunc) Form {
	if form.trans == nil {
		form.trans = map[string]HandlerFunc{}
	}
	form.trans[evt] = f
	return form
}

//Run execs the form
func (form FormImpl) Run(ws *websocket.Conn, app *App) error {
	msg := ""
	err := websocket.Message.Receive(ws, &msg)
	if err != nil {
		log.Println("Error on WS Receive", err)
		return err
	}
	println(msg, form.trans)
	f, present := form.trans[msg]
	if present {
		f(ws, app)
	} else {
		log.Println("Evt not found", msg)
	}
	return nil
}

//Initialize inits the form
func (form FormImpl) Initialize(ws *websocket.Conn) Form {
	log.Println("FormImpl Initialize")
	return form
}

//App is a Web Application representation
type App struct {
	WS          *websocket.Conn
	Forms       map[string]Form
	Data        map[string]interface{}
	CurrentForm Form
}

//GoTo replace the current form into app
func (app *App) GoTo(formName string) error {
	log.Println("App goto", formName)
	form, present := app.Forms[formName]
	if present {
		app.CurrentForm = form.Initialize(app.WS)
	} else {
		log.Println("[ERROR] Form not registred", formName)
	}
	return nil
}

//Run handle events
func (app *App) Run() {
	app.Data = map[string]interface{}{}
	for {
		err := app.CurrentForm.Run(app.WS, app)
		if err != nil {
			return
		}
	}
}

//Initialize inits the App
func (app *App) Initialize() {
	log.Println("App Initialize")
}

//AddForm add a new form to App
func (app *App) AddForm(name string, f Form) {
	if app.Forms == nil {
		app.Forms = map[string]Form{}
	}

	f.SetApp(app)
	app.Forms[name] = f
}
<|endoftext|>


<commit_before>// +build e2e

/*
Copyright 2020 The Knative Authors

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at

    http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/

package e2e

import (
	"context"
	"testing"

	pkgTest "knative.dev/pkg/test"
	rtesting "knative.dev/serving/pkg/testing/v1"
	"knative.dev/serving/test"
	v1test "knative.dev/serving/test/v1"
)

// TestHelloHttp2WithPortNameH2C validates that an http/2-only service can be
// reached if the portName is "h2c".
func TestHelloHttp2WithPortNameH2C(t *testing.T) {
	t.Parallel()

	clients := Setup(t)

	// hellohttp2 returns client errors (4xx) if contacted via http1.1,
	// and behaves like helloworld if called with http/2.
	names := test.ResourceNames{
		Service: test.ObjectNameForTest(t),
		Image:   "hellohttp2",
	}

	test.EnsureTearDown(t, clients, &names)

	t.Log("Creating a new Service")

	resources, err := v1test.CreateServiceReady(t, clients, &names, rtesting.WithNamedPort("h2c"))
	if err != nil {
		t.Fatalf("Failed to create initial Service: %v: %v", names.Service, err)
	}

	url := resources.Route.Status.URL.URL()
	if _, err := pkgTest.WaitForEndpointState(
		context.Background(),
		clients.KubeClient,
		t.Logf,
		url,
		v1test.RetryingRouteInconsistency(pkgTest.MatchesAllOf(pkgTest.IsStatusOK, pkgTest.MatchesBody(test.HelloHTTP2Text))),
		"HelloHttp2ServesTextOnH2C",
		test.ServingFlags.ResolvableDomain,
		test.AddRootCAtoTransport(context.Background(), t.Logf, clients, test.ServingFlags.HTTPS),
	); err != nil {
		t.Fatalf("The endpoint %s for Route %s didn't serve the expected text %q: %v", url, names.Route, test.HelloHTTP2Text, err)
	}
}

// TestHelloHttp2WithEmptyPortName validates that an http/2-only service
// is unreachable if the port name is not specified.
// TODO(knative/serving#4283): Once the feature is implemented, this test
// should succeed.
func TestHelloHttp2WithEmptyPortName(t *testing.T) {
	t.Parallel()

	clients := Setup(t)

	// hellohttp2 returns client errors (4xx) if contacted via http1.1,
	// and behaves like helloworld if called with http/2.
	names := test.ResourceNames{
		Service: test.ObjectNameForTest(t),
		Image:   "hellohttp2",
	}

	test.EnsureTearDown(t, clients, &names)

	t.Log("Creating a new Service")

	resources, err := v1test.CreateServiceReady(t, clients, &names, rtesting.WithNamedPort(""))
	if err != nil {
		t.Fatalf("Failed to create initial Service: %v: %v", names.Service, err)
	}

	url := resources.Route.Status.URL.URL()
	if _, err := pkgTest.WaitForEndpointState(
		context.Background(),
		clients.KubeClient,
		t.Logf,
		url,
		pkgTest.IsOneOfStatusCodes(426),
		"HelloHttp2ServesTextWithEmptyPort",
		test.ServingFlags.ResolvableDomain,
		test.AddRootCAtoTransport(context.Background(), t.Logf, clients, test.ServingFlags.HTTPS),
	); err != nil {
		t.Fatalf("The endpoint %s for Route %s didn't serve the expected status code 426: %v", url, names.Route, err)
	}
}
<commit_msg>Add RetryingRouteInconsistency to TestHelloHttp2WithEmptyPortName (#9687)<commit_after>// +build e2e

/*
Copyright 2020 The Knative Authors

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at

    http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/

package e2e

import (
	"context"
	"net/http"
	"testing"

	pkgTest "knative.dev/pkg/test"
	rtesting "knative.dev/serving/pkg/testing/v1"
	"knative.dev/serving/test"
	v1test "knative.dev/serving/test/v1"
)

// TestHelloHttp2WithPortNameH2C validates that an http/2-only service can be
// reached if the portName is "h2c".
func TestHelloHttp2WithPortNameH2C(t *testing.T) {
	t.Parallel()

	clients := Setup(t)

	// hellohttp2 returns client errors (4xx) if contacted via http1.1,
	// and behaves like helloworld if called with http/2.
	names := test.ResourceNames{
		Service: test.ObjectNameForTest(t),
		Image:   "hellohttp2",
	}

	test.EnsureTearDown(t, clients, &names)

	t.Log("Creating a new Service")

	resources, err := v1test.CreateServiceReady(t, clients, &names, rtesting.WithNamedPort("h2c"))
	if err != nil {
		t.Fatalf("Failed to create initial Service: %v: %v", names.Service, err)
	}

	url := resources.Route.Status.URL.URL()
	if _, err := pkgTest.WaitForEndpointState(
		context.Background(),
		clients.KubeClient,
		t.Logf,
		url,
		v1test.RetryingRouteInconsistency(pkgTest.MatchesAllOf(pkgTest.IsStatusOK, pkgTest.MatchesBody(test.HelloHTTP2Text))),
		"HelloHttp2ServesTextOnH2C",
		test.ServingFlags.ResolvableDomain,
		test.AddRootCAtoTransport(context.Background(), t.Logf, clients, test.ServingFlags.HTTPS),
	); err != nil {
		t.Fatalf("The endpoint %s for Route %s didn't serve the expected text %q: %v", url, names.Route, test.HelloHTTP2Text, err)
	}
}

// TestHelloHttp2WithEmptyPortName validates that an http/2-only service
// is unreachable if the port name is not specified.
// TODO(knative/serving#4283): Once the feature is implemented, this test
// should succeed.
func TestHelloHttp2WithEmptyPortName(t *testing.T) {
	t.Parallel()

	clients := Setup(t)

	// hellohttp2 returns client errors (4xx) if contacted via http1.1,
	// and behaves like helloworld if called with http/2.
	names := test.ResourceNames{
		Service: test.ObjectNameForTest(t),
		Image:   "hellohttp2",
	}

	test.EnsureTearDown(t, clients, &names)

	t.Log("Creating a new Service")

	resources, err := v1test.CreateServiceReady(t, clients, &names, rtesting.WithNamedPort(""))
	if err != nil {
		t.Fatalf("Failed to create initial Service: %v: %v", names.Service, err)
	}

	url := resources.Route.Status.URL.URL()
	if _, err := pkgTest.WaitForEndpointState(
		context.Background(),
		clients.KubeClient,
		t.Logf,
		url,
		v1test.RetryingRouteInconsistency(pkgTest.MatchesAllOf(pkgTest.IsOneOfStatusCodes(http.StatusUpgradeRequired))),
		"HelloHttp2ServesTextWithEmptyPort",
		test.ServingFlags.ResolvableDomain,
		test.AddRootCAtoTransport(context.Background(), t.Logf, clients, test.ServingFlags.HTTPS),
	); err != nil {
		t.Fatalf("The endpoint %s for Route %s didn't serve the expected status code %v: %v", url, names.Route, http.StatusUpgradeRequired, err)
	}

	t.Skip("HTP2 with empty port name is not implemented yet. See: https://github.com/knative/serving/issues/4283")
}
<|endoftext|>


<commit_before>// Copyright 2020 Authors of Cilium
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

package k8sTest

import (
	"context"
	"fmt"

	. "github.com/cilium/cilium/test/ginkgo-ext"
	"github.com/cilium/cilium/test/helpers"

	. "github.com/onsi/gomega"
)

var _ = Describe("K8sBandwidthTest", func() {
	const (
		testDS10       = "run=netperf-10"
		testDS25       = "run=netperf-25"
		testClientPod  = "run=netperf-client-pod"
		testClientHost = "run=netperf-client-host"

		maxRateDeviation = 5
		minBandwidth     = 1
	)

	var (
		kubectl        *helpers.Kubectl
		ciliumFilename string

		backgroundCancel       context.CancelFunc = func() {}
		backgroundError        error
		enableBackgroundReport = true

		podLabels = []string{
			testDS10,
			testDS25,
		}
	)

	BeforeAll(func() {
		kubectl = helpers.CreateKubectl(helpers.K8s1VMName(), logger)

		ciliumFilename = helpers.TimestampFilename("cilium.yaml")
		DeployCiliumAndDNS(kubectl, ciliumFilename)
	})

	AfterFailed(func() {
		kubectl.CiliumReport("cilium bpf bandwidth list", "cilium endpoint list")
	})

	JustBeforeEach(func() {
		if enableBackgroundReport {
			backgroundCancel, backgroundError = kubectl.BackgroundReport("uptime")
			Expect(backgroundError).To(BeNil(), "Cannot start background report process")
		}
	})

	JustAfterEach(func() {
		kubectl.ValidateNoErrorsInLogs(CurrentGinkgoTestDescription().Duration)
		backgroundCancel()
	})

	AfterEach(func() {
		ExpectAllPodsTerminated(kubectl)
	})

	AfterAll(func() {
		UninstallCiliumFromManifest(kubectl, ciliumFilename)
		kubectl.CloseSSHClient()
	})

	SkipContextIf(func() bool {
		return !helpers.RunsOnNetNextKernel()
	}, "Checks Bandwidth Rate-Limiting", func() {
		var demoYAML string

		BeforeAll(func() {
			demoYAML = helpers.ManifestGet(kubectl.BasePath(), "demo_bw.yaml")

			res := kubectl.ApplyDefault(demoYAML)
			res.ExpectSuccess("unable to apply %s", demoYAML)

			podLabels := []string{
				testDS10,
				testDS25,
				testClientPod,
				testClientHost,
			}
			for _, label := range podLabels {
				err := kubectl.WaitforPods(helpers.DefaultNamespace,
					fmt.Sprintf("-l %s", label), helpers.HelperTimeout)
				Expect(err).Should(BeNil())
			}
		})

		AfterAll(func() {
			_ = kubectl.Delete(demoYAML)
		})

		testNetperfFromPods := func(clientPodLabel, targetIP string, maxSessions, rate int) {
			pods, err := kubectl.GetPodNames(helpers.DefaultNamespace, clientPodLabel)
			ExpectWithOffset(1, err).Should(BeNil(), "cannot retrieve pod names by filter %q",
				clientPodLabel)
			for i := 1; i <= maxSessions; i++ {
				cmd := helpers.SuperNetperf(i, targetIP, helpers.TCP_MAERTS, "")
				for _, pod := range pods {
					By("Running %d netperf session from %s pod to pod with IP %s (expected rate: %d)",
						i, pod, targetIP, rate)
					res := kubectl.ExecPodCmd(helpers.DefaultNamespace, pod, cmd)
					ExpectWithOffset(1, res).Should(helpers.CMDSuccess(),
						"Request from %s pod to pod with IP %s failed", pod, targetIP)
					By("Session test completed, netperf result raw: %s", res.SingleOut())
					if rate > 0 {
						ExpectWithOffset(1, res.InRange(minBandwidth, rate+maxRateDeviation)).To(BeNil(),
							"Rate mismatch")
					}
				}
			}
		}

		testNetperf := func(podLabels []string, fromLabel string) {
			for _, label := range podLabels {
				podIPs, err := kubectl.GetPodsIPs(helpers.DefaultNamespace, label)
				ExpectWithOffset(1, err).Should(BeNil(), "Cannot retrieve pod IPs for %s", label)
				ExpectWithOffset(1, len(podIPs)).To(Equal(int(1)), "Expected pod IPs mismatch")
				rate := 0
				fmt.Sscanf(label, "run=netperf-%d", &rate)
				for _, podIP := range podIPs {
					testNetperfFromPods(fromLabel, podIP, 1, rate)
				}
			}
		}

		It("Checks Pod to Pod bandwidth, vxlan tunneling", func() {
			DeployCiliumOptionsAndDNS(kubectl, ciliumFilename, map[string]string{
				"tunnel": "vxlan",
			})
			testNetperf(podLabels, testClientPod)
			testNetperf(podLabels, testClientHost)
		})
		It("Checks Pod to Pod bandwidth, geneve tunneling", func() {
			DeployCiliumOptionsAndDNS(kubectl, ciliumFilename, map[string]string{
				"tunnel": "geneve",
			})
			testNetperf(podLabels, testClientPod)
			testNetperf(podLabels, testClientHost)
		})
		It("Checks Pod to Pod bandwidth, direct routing", func() {
			DeployCiliumOptionsAndDNS(kubectl, ciliumFilename, map[string]string{
				"tunnel":               "disabled",
				"autoDirectNodeRoutes": "true",
			})
			testNetperf(podLabels, testClientPod)
			testNetperf(podLabels, testClientHost)
		})
	})
})
<commit_msg>K8sBandwidthTest: enforce usage of bandwidth manager when deploying<commit_after>// Copyright 2020 Authors of Cilium
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

package k8sTest

import (
	"context"
	"fmt"

	. "github.com/cilium/cilium/test/ginkgo-ext"
	"github.com/cilium/cilium/test/helpers"

	. "github.com/onsi/gomega"
)

var _ = Describe("K8sBandwidthTest", func() {
	const (
		testDS10       = "run=netperf-10"
		testDS25       = "run=netperf-25"
		testClientPod  = "run=netperf-client-pod"
		testClientHost = "run=netperf-client-host"

		maxRateDeviation = 5
		minBandwidth     = 1
	)

	var (
		kubectl        *helpers.Kubectl
		ciliumFilename string

		backgroundCancel       context.CancelFunc = func() {}
		backgroundError        error
		enableBackgroundReport = true

		podLabels = []string{
			testDS10,
			testDS25,
		}
	)

	BeforeAll(func() {
		kubectl = helpers.CreateKubectl(helpers.K8s1VMName(), logger)

		ciliumFilename = helpers.TimestampFilename("cilium.yaml")
		DeployCiliumOptionsAndDNS(kubectl, ciliumFilename, map[string]string{
			"bandwidthManager": "true",
		})
	})

	AfterFailed(func() {
		kubectl.CiliumReport("cilium bpf bandwidth list", "cilium endpoint list")
	})

	JustBeforeEach(func() {
		if enableBackgroundReport {
			backgroundCancel, backgroundError = kubectl.BackgroundReport("uptime")
			Expect(backgroundError).To(BeNil(), "Cannot start background report process")
		}
	})

	JustAfterEach(func() {
		kubectl.ValidateNoErrorsInLogs(CurrentGinkgoTestDescription().Duration)
		backgroundCancel()
	})

	AfterEach(func() {
		ExpectAllPodsTerminated(kubectl)
	})

	AfterAll(func() {
		UninstallCiliumFromManifest(kubectl, ciliumFilename)
		kubectl.CloseSSHClient()
	})

	SkipContextIf(func() bool {
		return !helpers.RunsOnNetNextKernel()
	}, "Checks Bandwidth Rate-Limiting", func() {
		var demoYAML string

		BeforeAll(func() {
			demoYAML = helpers.ManifestGet(kubectl.BasePath(), "demo_bw.yaml")

			res := kubectl.ApplyDefault(demoYAML)
			res.ExpectSuccess("unable to apply %s", demoYAML)

			podLabels := []string{
				testDS10,
				testDS25,
				testClientPod,
				testClientHost,
			}
			for _, label := range podLabels {
				err := kubectl.WaitforPods(helpers.DefaultNamespace,
					fmt.Sprintf("-l %s", label), helpers.HelperTimeout)
				Expect(err).Should(BeNil())
			}
		})

		AfterAll(func() {
			_ = kubectl.Delete(demoYAML)
		})

		testNetperfFromPods := func(clientPodLabel, targetIP string, maxSessions, rate int) {
			pods, err := kubectl.GetPodNames(helpers.DefaultNamespace, clientPodLabel)
			ExpectWithOffset(1, err).Should(BeNil(), "cannot retrieve pod names by filter %q",
				clientPodLabel)
			for i := 1; i <= maxSessions; i++ {
				cmd := helpers.SuperNetperf(i, targetIP, helpers.TCP_MAERTS, "")
				for _, pod := range pods {
					By("Running %d netperf session from %s pod to pod with IP %s (expected rate: %d)",
						i, pod, targetIP, rate)
					res := kubectl.ExecPodCmd(helpers.DefaultNamespace, pod, cmd)
					ExpectWithOffset(1, res).Should(helpers.CMDSuccess(),
						"Request from %s pod to pod with IP %s failed", pod, targetIP)
					By("Session test completed, netperf result raw: %s", res.SingleOut())
					if rate > 0 {
						ExpectWithOffset(1, res.InRange(minBandwidth, rate+maxRateDeviation)).To(BeNil(),
							"Rate mismatch")
					}
				}
			}
		}

		testNetperf := func(podLabels []string, fromLabel string) {
			for _, label := range podLabels {
				podIPs, err := kubectl.GetPodsIPs(helpers.DefaultNamespace, label)
				ExpectWithOffset(1, err).Should(BeNil(), "Cannot retrieve pod IPs for %s", label)
				ExpectWithOffset(1, len(podIPs)).To(Equal(int(1)), "Expected pod IPs mismatch")
				rate := 0
				fmt.Sscanf(label, "run=netperf-%d", &rate)
				for _, podIP := range podIPs {
					testNetperfFromPods(fromLabel, podIP, 1, rate)
				}
			}
		}

		It("Checks Pod to Pod bandwidth, vxlan tunneling", func() {
			DeployCiliumOptionsAndDNS(kubectl, ciliumFilename, map[string]string{
				"bandwidthManager": "true",
				"tunnel":           "vxlan",
			})
			testNetperf(podLabels, testClientPod)
			testNetperf(podLabels, testClientHost)
		})
		It("Checks Pod to Pod bandwidth, geneve tunneling", func() {
			DeployCiliumOptionsAndDNS(kubectl, ciliumFilename, map[string]string{
				"bandwidthManager": "true",
				"tunnel":           "geneve",
			})
			testNetperf(podLabels, testClientPod)
			testNetperf(podLabels, testClientHost)
		})
		It("Checks Pod to Pod bandwidth, direct routing", func() {
			DeployCiliumOptionsAndDNS(kubectl, ciliumFilename, map[string]string{
				"bandwidthManager":     "true",
				"tunnel":               "disabled",
				"autoDirectNodeRoutes": "true",
			})
			testNetperf(podLabels, testClientPod)
			testNetperf(podLabels, testClientHost)
		})
	})
})
<|endoftext|>


<commit_before>package main

const Version = "0.1.4"
<commit_msg>Bump version number to 1.0.5 to force rebuild.<commit_after>package main

const Version = "0.1.5"
<|endoftext|>


<commit_before>//
// Copyright © 2016 Guy M. Allard
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//

package main

/*
	Provide package version information.  A nod to the concept of semver.

	Example:
		go run $GOPATH/src/github.com/gmallard/stompngo_examples/version.go

*/

import (
	"fmt"
)

var (
	pref  = "v"          // Prefix

	major = "1"          // Major

	minor = "0"          // Minor

	patch = "3"          // Patch

	//patch = "2.plvl.005" // Patch
)

func main() {
	fmt.Printf("%s%s.%s.%s\n", pref, major, minor, patch)
}
<commit_msg>Start next dev round.<commit_after>//
// Copyright © 2016 Guy M. Allard
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//

package main

/*
	Provide package version information.  A nod to the concept of semver.

	Example:
		go run $GOPATH/src/github.com/gmallard/stompngo_examples/version.go

*/

import (
	"fmt"
)

var (
	pref = "v" // Prefix

	major = "1" // Major

	minor = "0" // Minor

	//patch = "3"          // Patch

	patch = "2.plvl.001" // Patch
)

func main() {
	fmt.Printf("%s%s.%s.%s\n", pref, major, minor, patch)
}
<|endoftext|>


<commit_before>package main

// VERSION - snagsby version
const VERSION = "0.1.2"
<commit_msg>Bump to 0.1.3<commit_after>package main

// VERSION - snagsby version
const VERSION = "0.1.3"
<|endoftext|>


<commit_before>package nsq

const VERSION = "0.1.6"
<commit_msg>bump versions<commit_after>package nsq

const VERSION = "0.1.7"
<|endoftext|>


<commit_before>package storm

// Version of Storm
const Version = "0.8.1"
<commit_msg>Bump to v1.0.0<commit_after>package storm

// Version of Storm
const Version = "1.0.0"
<|endoftext|>


<commit_before>package main

const VERSION = "v1.0.2"
<commit_msg>version bump v1.1.0<commit_after>package main

const VERSION = "v1.1.0"
<|endoftext|>


<commit_before>package swag

// Version of swag.
const Version = "v1.7.9"
<commit_msg>chore: update version.go (#1144)<commit_after>package swag

// Version of swag.
const Version = "v1.8.0"
<|endoftext|>


<commit_before>package library

import (
	"encoding/json"
	"errors"
	"github.com/gorilla/websocket"
	"github.com/nytlabs/streamtools/st/blocks" // blocks
	"github.com/nytlabs/streamtools/st/util"   // utils
	"log"
	"net/http"
	"time"
)

// specify those channels we're going to use to communicate with streamtools
type toWebsocket struct {
	blocks.Block
	queryrule chan chan interface{}
	inrule    chan interface{}
	in        chan interface{}
	out       chan interface{}
	quit      chan interface{}
}

// we need to build a simple factory so that streamtools can make new blocks of this kind
func NewToWebsocket() blocks.BlockInterface {
	return &toWebsocket{}
}

// Setup is called once before running the block. We build up the channels and specify what kind of block this is.
func (b *toWebsocket) Setup() {
	b.Kind = "toWebsocket"
	b.in = b.InRoute("in")
	b.inrule = b.InRoute("rule")
	b.queryrule = b.QueryRoute("rule")
	b.quit = b.Quit()
}

var h = hub{
	broadcast:   make(chan []byte),
	register:    make(chan *connection),
	unregister:  make(chan *connection),
	connections: make(map[*connection]bool),
}

// Run is the block's main loop. Here we listen on the different channels we set up.
func (b *toWebsocket) Run() {

	var addr string
	var err error

	go h.run()

	for {
		select {
		case ruleI := <-b.inrule:
			// set a parameter of the block
			rule, ok := ruleI.(map[string]interface{})
			if !ok {
				b.Error(errors.New("couldn't assert rule to map"))
			}
			addr, err = util.ParseString(rule, "port")
			if err != nil {
				b.Error(err)
			}
			http.HandleFunc("/ws", serveWs)
			go http.ListenAndServe(":"+addr, nil)
			if err != nil {
				b.Error(err)
			}
		case <-b.quit:
			// quit the block
			return
		case msg := <-b.in:
			if addr == "" {
				continue
			}
			out, err := json.Marshal(msg)
			if err != nil {
				b.Error(err)
			}
			h.broadcast <- out

		case c := <-b.queryrule:
			// deal with a query request
			c <- map[string]interface{}{
				"port": addr,
			}
		}
	}
	log.Println("done")
}

type hub struct {
	// Registered connections.
	connections map[*connection]bool

	// Inbound messages from the connections.
	broadcast chan []byte

	// Register requests from the connections.
	register chan *connection

	// Unregister requests from connections.
	unregister chan *connection
}

func (h *hub) run() {
	for {
		select {
		case c := <-h.register:
			h.connections[c] = true
		case c := <-h.unregister:
			delete(h.connections, c)
			close(c.send)
		case m := <-h.broadcast:
			for c := range h.connections {
				select {
				case c.send <- m:
				default:
					close(c.send)
					delete(h.connections, c)
				}
			}
		}
	}
}

const (
	// Time allowed to write a message to the peer.
	writeWait = 10 * time.Second

	// Time allowed to read the next pong message from the peer.
	pongWait = 60 * time.Second

	// Send pings to peer with this period. Must be less than pongWait.
	pingPeriod = (pongWait * 9) / 10

	// Maximum message size allowed from peer.
	maxMessageSize = 512
)

// connection is an middleman between the websocket connection and the hub.
type connection struct {
	// The websocket connection.
	ws *websocket.Conn

	// Buffered channel of outbound messages.
	send chan []byte
}

// readPump pumps messages from the websocket connection to the hub.
func (c *connection) readPump() {
	defer func() {
		h.unregister <- c
		c.ws.Close()
	}()
	c.ws.SetReadLimit(maxMessageSize)
	c.ws.SetReadDeadline(time.Now().Add(pongWait))
	c.ws.SetPongHandler(func(string) error { c.ws.SetReadDeadline(time.Now().Add(pongWait)); return nil })
	for {
		_, message, err := c.ws.ReadMessage()
		if err != nil {
			break
		}
		h.broadcast <- message
	}
}

// write writes a message with the given message type and payload.
func (c *connection) write(mt int, payload []byte) error {
	c.ws.SetWriteDeadline(time.Now().Add(writeWait))
	return c.ws.WriteMessage(mt, payload)
}

// writePump pumps messages from the hub to the websocket connection.
func (c *connection) writePump() {
	ticker := time.NewTicker(pingPeriod)
	defer func() {
		ticker.Stop()
		c.ws.Close()
	}()
	for {
		select {
		case message, ok := <-c.send:
			if !ok {
				c.write(websocket.CloseMessage, []byte{})
				return
			}
			if err := c.write(websocket.TextMessage, message); err != nil {
				return
			}
		case <-ticker.C:
			if err := c.write(websocket.PingMessage, []byte{}); err != nil {
				return
			}
		}
	}
}

// serverWs handles webocket requests from the peer.
func serveWs(w http.ResponseWriter, r *http.Request) {
	if r.Method != "GET" {
		http.Error(w, "Method not allowed", 405)
		return
	}
	/*
		if r.Header.Get("Origin") != "http://"+r.Host {
			log.Println("403")
			http.Error(w, "Origin not allowed", 403)
			return
		}
	*/
	ws, err := websocket.Upgrade(w, r, nil, 1024, 1024)
	if _, ok := err.(websocket.HandshakeError); ok {
		http.Error(w, "Not a websocket handshake", 400)
		return
	} else if err != nil {
		log.Println(err)
		return
	}
	c := &connection{send: make(chan []byte, 256), ws: ws}
	h.register <- c
	go c.writePump()
	c.readPump()
}
<commit_msg>removed toWebsocket cos it's pointless now<commit_after><|endoftext|>


<commit_before>package gitmedia

import (
	".."
	"../client"
)

type SyncCommand struct {
	*Command
}

func (c *SyncCommand) Setup() {
}

func (c *SyncCommand) Run() {
	q := gitmedia.UploadQueue()
	q.Walk(func(id string, body []byte) error {
		sha := string(body)
		path := gitmedia.LocalMediaPath(sha)
		err := gitmediaclient.Send(path)
		if err != nil {
			gitmedia.Panic(err, "error uploading file %s", sha)
		}

		if err := q.Del(id); err != nil {
			gitmedia.Panic(err, "error removing %s from queue", sha)
		}
	})
}

func init() {
	registerCommand("sync", func(c *Command) RunnableCommand {
		return &SyncCommand{Command: c}
	})
}
<commit_msg>ンンンンン ンンンン<commit_after>package gitmedia

import (
	".."
	"../client"
)

type SyncCommand struct {
	*Command
}

func (c *SyncCommand) Setup() {
}

func (c *SyncCommand) Run() {
	q := gitmedia.UploadQueue()
	q.Walk(func(id string, body []byte) error {
		sha := string(body)
		path := gitmedia.LocalMediaPath(sha)
		err := gitmediaclient.Send(path)
		if err != nil {
			gitmedia.Panic(err, "error uploading file %s", sha)
		}

		if err := q.Del(id); err != nil {
			gitmedia.Panic(err, "error removing %s from queue", sha)
		}
		return nil
	})
}

func init() {
	registerCommand("sync", func(c *Command) RunnableCommand {
		return &SyncCommand{Command: c}
	})
}
<|endoftext|>


<commit_before>package http

import (
	"errors"
	"fmt"
	"io"
	"net/http"
	"strconv"
	"strings"

	"github.com/ipfs/go-ipfs/Godeps/_workspace/src/github.com/rs/cors"

	cmds "github.com/ipfs/go-ipfs/commands"
	u "github.com/ipfs/go-ipfs/util"
)

var log = u.Logger("commands/http")

// the internal handler for the API
type internalHandler struct {
	ctx  cmds.Context
	root *cmds.Command
}

// The Handler struct is funny because we want to wrap our internal handler
// with CORS while keeping our fields.
type Handler struct {
	internalHandler
	corsHandler http.Handler
}

var ErrNotFound = errors.New("404 page not found")

const (
	streamHeader           = "X-Stream-Output"
	channelHeader          = "X-Chunked-Output"
	contentTypeHeader      = "Content-Type"
	contentLengthHeader    = "Content-Length"
	transferEncodingHeader = "Transfer-Encoding"
	applicationJson        = "application/json"
)

var mimeTypes = map[string]string{
	cmds.JSON: "application/json",
	cmds.XML:  "application/xml",
	cmds.Text: "text/plain",
}

func NewHandler(ctx cmds.Context, root *cmds.Command, allowedOrigin string) *Handler {
	// allow whitelisted origins (so we can make API requests from the browser)
	if len(allowedOrigin) > 0 {
		log.Info("Allowing API requests from origin: " + allowedOrigin)
	}

	// Create a handler for the API.
	internal := internalHandler{ctx, root}

	// Create a CORS object for wrapping the internal handler.
	c := cors.New(cors.Options{
		AllowedMethods: []string{"GET", "POST", "PUT"},

		// use AllowOriginFunc instead of AllowedOrigins because we want to be
		// restrictive by default.
		AllowOriginFunc: func(origin string) bool {
			return (allowedOrigin == "*") || (origin == allowedOrigin)
		},
	})

	// Wrap the internal handler with CORS handling-middleware.
	return &Handler{internal, c.Handler(internal)}
}

func (i internalHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
	log.Debug("Incoming API request: ", r.URL)

	// error on external referers (to prevent CSRF attacks)
	referer := r.Referer()
	scheme := r.URL.Scheme
	if len(scheme) == 0 {
		scheme = "http"
	}
	host := fmt.Sprintf("%s://%s/", scheme, r.Host)
	// empty string means the user isn't following a link (they are directly typing in the url)
	if referer != "" && !strings.HasPrefix(referer, host) {
		w.WriteHeader(http.StatusForbidden)
		w.Write([]byte("403 - Forbidden"))
		return
	}

	req, err := Parse(r, i.root)
	if err != nil {
		if err == ErrNotFound {
			w.WriteHeader(http.StatusNotFound)
		} else {
			w.WriteHeader(http.StatusBadRequest)
		}
		w.Write([]byte(err.Error()))
		return
	}

	// get the node's context to pass into the commands.
	node, err := i.ctx.GetNode()
	if err != nil {
		err = fmt.Errorf("cmds/http: couldn't GetNode(): %s", err)
		http.Error(w, err.Error(), http.StatusInternalServerError)
		return
	}

	//ps: take note of the name clash - commands.Context != context.Context
	req.SetInvocContext(i.ctx)
	err = req.SetRootContext(node.Context())
	if err != nil {
		http.Error(w, err.Error(), http.StatusInternalServerError)
		return
	}

	// call the command
	res := i.root.Call(req)

	// set the Content-Type based on res output
	if _, ok := res.Output().(io.Reader); ok {
		// we don't set the Content-Type for streams, so that browsers can MIME-sniff the type themselves
		// we set this header so clients have a way to know this is an output stream
		// (not marshalled command output)
		// TODO: set a specific Content-Type if the command response needs it to be a certain type
		w.Header().Set(streamHeader, "1")

	} else {
		enc, found, err := req.Option(cmds.EncShort).String()
		if err != nil || !found {
			w.WriteHeader(http.StatusInternalServerError)
			return
		}
		mime := mimeTypes[enc]
		w.Header().Set(contentTypeHeader, mime)
	}

	// set the Content-Length from the response length
	if res.Length() > 0 {
		w.Header().Set(contentLengthHeader, strconv.FormatUint(res.Length(), 10))
	}

	// if response contains an error, write an HTTP error status code
	if e := res.Error(); e != nil {
		if e.Code == cmds.ErrClient {
			w.WriteHeader(http.StatusBadRequest)
		} else {
			w.WriteHeader(http.StatusInternalServerError)
		}
	}

	out, err := res.Reader()
	if err != nil {
		w.Header().Set(contentTypeHeader, "text/plain")
		w.WriteHeader(http.StatusInternalServerError)
		w.Write([]byte(err.Error()))
		return
	}

	// if output is a channel and user requested streaming channels,
	// use chunk copier for the output
	_, isChan := res.Output().(chan interface{})
	if !isChan {
		_, isChan = res.Output().(<-chan interface{})
	}

	streamChans, _, _ := req.Option("stream-channels").Bool()
	if isChan && streamChans {
		// w.WriteString(transferEncodingHeader + ": chunked\r\n")
		// w.Header().Set(channelHeader, "1")
		// w.WriteHeader(200)
		err = copyChunks(applicationJson, w, out)
		if err != nil {
			log.Debug("copy chunks error: ", err)
		}
		return
	}

	err = flushCopy(w, out)
	if err != nil {
		log.Debug("Flush copy returned an error: ", err)
	}
}

func (i Handler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
	// Call the CORS handler which wraps the internal handler.
	i.corsHandler.ServeHTTP(w, r)
}

// flushCopy Copies from an io.Reader to a http.ResponseWriter.
// Flushes chunks over HTTP stream as they are read (if supported by transport).
func flushCopy(w http.ResponseWriter, out io.Reader) error {
	if _, ok := w.(http.Flusher); !ok {
		return copyChunks("", w, out)
	}

	_, err := io.Copy(&flushResponse{w}, out)
	return err
}

// Copies from an io.Reader to a http.ResponseWriter.
// Flushes chunks over HTTP stream as they are read (if supported by transport).
func copyChunks(contentType string, w http.ResponseWriter, out io.Reader) error {
	hijacker, ok := w.(http.Hijacker)
	if !ok {
		return errors.New("Could not create hijacker")
	}
	conn, writer, err := hijacker.Hijack()
	if err != nil {
		return err
	}
	defer conn.Close()

	writer.WriteString("HTTP/1.1 200 OK\r\n")
	if contentType != "" {
		writer.WriteString(contentTypeHeader + ": " + contentType + "\r\n")
	}
	writer.WriteString(transferEncodingHeader + ": chunked\r\n")
	writer.WriteString(channelHeader + ": 1\r\n\r\n")

	buf := make([]byte, 32*1024)

	for {
		n, err := out.Read(buf)

		if n > 0 {
			length := fmt.Sprintf("%x\r\n", n)
			writer.WriteString(length)

			_, err := writer.Write(buf[0:n])
			if err != nil {
				return err
			}

			writer.WriteString("\r\n")
			writer.Flush()
		}

		if err != nil && err != io.EOF {
			return err
		}
		if err == io.EOF {
			break
		}
	}

	writer.WriteString("0\r\n\r\n")
	writer.Flush()

	return nil
}

type flushResponse struct {
	W http.ResponseWriter
}

func (fr *flushResponse) Write(buf []byte) (int, error) {
	n, err := fr.W.Write(buf)
	if err != nil {
		return n, err
	}

	if flusher, ok := fr.W.(http.Flusher); ok {
		flusher.Flush()
	}
	return n, err
}
<commit_msg>http/client: log errors when stream copy fails<commit_after>package http

import (
	"errors"
	"fmt"
	"io"
	"net/http"
	"strconv"
	"strings"

	"github.com/ipfs/go-ipfs/Godeps/_workspace/src/github.com/rs/cors"

	cmds "github.com/ipfs/go-ipfs/commands"
	u "github.com/ipfs/go-ipfs/util"
)

var log = u.Logger("commands/http")

// the internal handler for the API
type internalHandler struct {
	ctx  cmds.Context
	root *cmds.Command
}

// The Handler struct is funny because we want to wrap our internal handler
// with CORS while keeping our fields.
type Handler struct {
	internalHandler
	corsHandler http.Handler
}

var ErrNotFound = errors.New("404 page not found")

const (
	streamHeader           = "X-Stream-Output"
	channelHeader          = "X-Chunked-Output"
	contentTypeHeader      = "Content-Type"
	contentLengthHeader    = "Content-Length"
	transferEncodingHeader = "Transfer-Encoding"
	applicationJson        = "application/json"
)

var mimeTypes = map[string]string{
	cmds.JSON: "application/json",
	cmds.XML:  "application/xml",
	cmds.Text: "text/plain",
}

func NewHandler(ctx cmds.Context, root *cmds.Command, allowedOrigin string) *Handler {
	// allow whitelisted origins (so we can make API requests from the browser)
	if len(allowedOrigin) > 0 {
		log.Info("Allowing API requests from origin: " + allowedOrigin)
	}

	// Create a handler for the API.
	internal := internalHandler{ctx, root}

	// Create a CORS object for wrapping the internal handler.
	c := cors.New(cors.Options{
		AllowedMethods: []string{"GET", "POST", "PUT"},

		// use AllowOriginFunc instead of AllowedOrigins because we want to be
		// restrictive by default.
		AllowOriginFunc: func(origin string) bool {
			return (allowedOrigin == "*") || (origin == allowedOrigin)
		},
	})

	// Wrap the internal handler with CORS handling-middleware.
	return &Handler{internal, c.Handler(internal)}
}

func (i internalHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
	log.Debug("Incoming API request: ", r.URL)

	// error on external referers (to prevent CSRF attacks)
	referer := r.Referer()
	scheme := r.URL.Scheme
	if len(scheme) == 0 {
		scheme = "http"
	}
	host := fmt.Sprintf("%s://%s/", scheme, r.Host)
	// empty string means the user isn't following a link (they are directly typing in the url)
	if referer != "" && !strings.HasPrefix(referer, host) {
		w.WriteHeader(http.StatusForbidden)
		w.Write([]byte("403 - Forbidden"))
		return
	}

	req, err := Parse(r, i.root)
	if err != nil {
		if err == ErrNotFound {
			w.WriteHeader(http.StatusNotFound)
		} else {
			w.WriteHeader(http.StatusBadRequest)
		}
		w.Write([]byte(err.Error()))
		return
	}

	// get the node's context to pass into the commands.
	node, err := i.ctx.GetNode()
	if err != nil {
		err = fmt.Errorf("cmds/http: couldn't GetNode(): %s", err)
		http.Error(w, err.Error(), http.StatusInternalServerError)
		return
	}

	//ps: take note of the name clash - commands.Context != context.Context
	req.SetInvocContext(i.ctx)
	err = req.SetRootContext(node.Context())
	if err != nil {
		http.Error(w, err.Error(), http.StatusInternalServerError)
		return
	}

	// call the command
	res := i.root.Call(req)

	// set the Content-Type based on res output
	if _, ok := res.Output().(io.Reader); ok {
		// we don't set the Content-Type for streams, so that browsers can MIME-sniff the type themselves
		// we set this header so clients have a way to know this is an output stream
		// (not marshalled command output)
		// TODO: set a specific Content-Type if the command response needs it to be a certain type
		w.Header().Set(streamHeader, "1")

	} else {
		enc, found, err := req.Option(cmds.EncShort).String()
		if err != nil || !found {
			w.WriteHeader(http.StatusInternalServerError)
			return
		}
		mime := mimeTypes[enc]
		w.Header().Set(contentTypeHeader, mime)
	}

	// set the Content-Length from the response length
	if res.Length() > 0 {
		w.Header().Set(contentLengthHeader, strconv.FormatUint(res.Length(), 10))
	}

	// if response contains an error, write an HTTP error status code
	if e := res.Error(); e != nil {
		if e.Code == cmds.ErrClient {
			w.WriteHeader(http.StatusBadRequest)
		} else {
			w.WriteHeader(http.StatusInternalServerError)
		}
	}

	out, err := res.Reader()
	if err != nil {
		w.Header().Set(contentTypeHeader, "text/plain")
		w.WriteHeader(http.StatusInternalServerError)
		w.Write([]byte(err.Error()))
		return
	}

	// if output is a channel and user requested streaming channels,
	// use chunk copier for the output
	_, isChan := res.Output().(chan interface{})
	if !isChan {
		_, isChan = res.Output().(<-chan interface{})
	}

	streamChans, _, _ := req.Option("stream-channels").Bool()
	if isChan && streamChans {
		if err := copyChunks(applicationJson, w, out); err != nil {
			log.Error("error while writing stream", err)
		}
		return
	}

	if err := flushCopy(w, out); err != nil {
		log.Error("error while writing stream", err)
	}
}

func (i Handler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
	// Call the CORS handler which wraps the internal handler.
	i.corsHandler.ServeHTTP(w, r)
}

// flushCopy Copies from an io.Reader to a http.ResponseWriter.
// Flushes chunks over HTTP stream as they are read (if supported by transport).
func flushCopy(w http.ResponseWriter, out io.Reader) error {
	if _, ok := w.(http.Flusher); !ok {
		return copyChunks("", w, out)
	}

	_, err := io.Copy(&flushResponse{w}, out)
	return err
}

// Copies from an io.Reader to a http.ResponseWriter.
// Flushes chunks over HTTP stream as they are read (if supported by transport).
func copyChunks(contentType string, w http.ResponseWriter, out io.Reader) error {
	hijacker, ok := w.(http.Hijacker)
	if !ok {
		return errors.New("Could not create hijacker")
	}
	conn, writer, err := hijacker.Hijack()
	if err != nil {
		return err
	}
	defer conn.Close()

	writer.WriteString("HTTP/1.1 200 OK\r\n")
	if contentType != "" {
		writer.WriteString(contentTypeHeader + ": " + contentType + "\r\n")
	}
	writer.WriteString(transferEncodingHeader + ": chunked\r\n")
	writer.WriteString(channelHeader + ": 1\r\n\r\n")

	buf := make([]byte, 32*1024)

	for {
		n, err := out.Read(buf)

		if n > 0 {
			length := fmt.Sprintf("%x\r\n", n)
			writer.WriteString(length)

			_, err := writer.Write(buf[0:n])
			if err != nil {
				return err
			}

			writer.WriteString("\r\n")
			writer.Flush()
		}

		if err != nil && err != io.EOF {
			return err
		}
		if err == io.EOF {
			break
		}
	}

	writer.WriteString("0\r\n\r\n")
	writer.Flush()

	return nil
}

type flushResponse struct {
	W http.ResponseWriter
}

func (fr *flushResponse) Write(buf []byte) (int, error) {
	n, err := fr.W.Write(buf)
	if err != nil {
		return n, err
	}

	if flusher, ok := fr.W.(http.Flusher); ok {
		flusher.Flush()
	}
	return n, err
}
<|endoftext|>


<commit_before>// Code generated by protoc-gen-go.
// source: zvelo/msg/stream_result.proto
// DO NOT EDIT!

package msg

import proto "github.com/golang/protobuf/proto"
import fmt "fmt"
import math "math"

// Reference imports to suppress errors if they are not otherwise used.
var _ = proto.Marshal
var _ = fmt.Errorf
var _ = math.Inf

type StreamResult struct {
	Url     string   `protobuf:"bytes,1,opt,name=url" json:"url,omitempty"`
	Dataset *DataSet `protobuf:"bytes,2,opt,name=dataset" json:"dataset,omitempty"`
}

func (m *StreamResult) Reset()                    { *m = StreamResult{} }
func (m *StreamResult) String() string            { return proto.CompactTextString(m) }
func (*StreamResult) ProtoMessage()               {}
func (*StreamResult) Descriptor() ([]byte, []int) { return fileDescriptor6, []int{0} }

func (m *StreamResult) GetDataset() *DataSet {
	if m != nil {
		return m.Dataset
	}
	return nil
}

type StreamResults struct {
	Values []*StreamResult `protobuf:"bytes,1,rep,name=values" json:"values,omitempty"`
}

func (m *StreamResults) Reset()                    { *m = StreamResults{} }
func (m *StreamResults) String() string            { return proto.CompactTextString(m) }
func (*StreamResults) ProtoMessage()               {}
func (*StreamResults) Descriptor() ([]byte, []int) { return fileDescriptor6, []int{1} }

func (m *StreamResults) GetValues() []*StreamResult {
	if m != nil {
		return m.Values
	}
	return nil
}

func init() {
	proto.RegisterType((*StreamResult)(nil), "msg.StreamResult")
	proto.RegisterType((*StreamResults)(nil), "msg.StreamResults")
}

func init() { proto.RegisterFile("zvelo/msg/stream_result.proto", fileDescriptor6) }

var fileDescriptor6 = []byte{
	// 175 bytes of a gzipped FileDescriptorProto
	0x1f, 0x8b, 0x08, 0x00, 0x00, 0x09, 0x6e, 0x88, 0x02, 0xff, 0xe2, 0x92, 0xad, 0x2a, 0x4b, 0xcd,
	0xc9, 0xd7, 0xcf, 0x2d, 0x4e, 0xd7, 0x2f, 0x2e, 0x29, 0x4a, 0x4d, 0xcc, 0x8d, 0x2f, 0x4a, 0x2d,
	0x2e, 0xcd, 0x29, 0xd1, 0x2b, 0x28, 0xca, 0x2f, 0xc9, 0x17, 0x62, 0xce, 0x2d, 0x4e, 0x97, 0x12,
	0x47, 0xa8, 0x49, 0x49, 0x2c, 0x49, 0x2c, 0x4e, 0x85, 0xca, 0x2a, 0x79, 0x70, 0xf1, 0x04, 0x83,
	0x35, 0x05, 0x81, 0xf5, 0x08, 0x09, 0x70, 0x31, 0x97, 0x16, 0xe5, 0x48, 0x30, 0x2a, 0x30, 0x6a,
	0x70, 0x06, 0x81, 0x98, 0x42, 0x6a, 0x5c, 0xec, 0x50, 0x2d, 0x12, 0x4c, 0x0a, 0x8c, 0x1a, 0xdc,
	0x46, 0x3c, 0x7a, 0xb9, 0xc5, 0xe9, 0x7a, 0x2e, 0x89, 0x25, 0x89, 0xc1, 0xa9, 0x25, 0x41, 0x30,
	0x49, 0x25, 0x2b, 0x2e, 0x5e, 0x64, 0x93, 0x8a, 0x85, 0x34, 0xb9, 0xd8, 0xca, 0x12, 0x73, 0x4a,
	0x53, 0x8b, 0x25, 0x18, 0x15, 0x98, 0x35, 0xb8, 0x8d, 0x04, 0xc1, 0xfa, 0x90, 0xd5, 0x04, 0x41,
	0x15, 0x38, 0xf1, 0x45, 0xf1, 0x80, 0x1d, 0xa8, 0x97, 0x09, 0x76, 0x63, 0x12, 0x1b, 0xd8, 0x71,
	0xc6, 0x80, 0x00, 0x00, 0x00, 0xff, 0xff, 0x08, 0xef, 0x72, 0xb0, 0xdb, 0x00, 0x00, 0x00,
}
<commit_msg>Remove outdated file<commit_after><|endoftext|>


<commit_before>// Copyright 2016 Keybase Inc. All rights reserved.
// Use of this source code is governed by a BSD
// license that can be found in the LICENSE file.

package libkbfs

import (
	"reflect"
	"sync"

	"github.com/keybase/client/go/libkb"

	"golang.org/x/net/context"
)

// FolderBranchStatus is a simple data structure describing the
// current status of a particular folder-branch.  It is suitable for
// encoding directly as JSON.
type FolderBranchStatus struct {
	Staged       bool
	BranchID     string
	HeadWriter   libkb.NormalizedUsername
	DiskUsage    uint64
	RekeyPending bool
	FolderID     string
	Revision     MetadataRevision

	// DirtyPaths are files that have been written, but not flushed.
	// They do not represent unstaged changes in your local instance.
	DirtyPaths []string

	// If we're in the staged state, these summaries show the
	// diverging operations per-file
	Unmerged []*crChainSummary
	Merged   []*crChainSummary

	Journal *TLFJournalStatus `json:",omitempty"`
}

// KBFSStatus represents the content of the top-level status file. It is
// suitable for encoding directly as JSON.
// TODO: implement magical status update like FolderBranchStatus
type KBFSStatus struct {
	CurrentUser     string
	IsConnected     bool
	UsageBytes      int64
	LimitBytes      int64
	FailingServices map[string]error
	JournalServer   *JournalServerStatus `json:",omitempty"`
}

// StatusUpdate is a dummy type used to indicate status has been updated.
type StatusUpdate struct{}

// folderBranchStatusKeeper holds and updates the status for a given
// folder-branch, and produces FolderBranchStatus instances suitable
// for callers outside this package to consume.
type folderBranchStatusKeeper struct {
	config    Config
	nodeCache NodeCache

	md         ImmutableRootMetadata
	dirtyNodes map[NodeID]Node
	unmerged   []*crChainSummary
	merged     []*crChainSummary
	dataMutex  sync.Mutex

	updateChan  chan StatusUpdate
	updateMutex sync.Mutex
}

func newFolderBranchStatusKeeper(
	config Config, nodeCache NodeCache) *folderBranchStatusKeeper {
	return &folderBranchStatusKeeper{
		config:     config,
		nodeCache:  nodeCache,
		dirtyNodes: make(map[NodeID]Node),
		updateChan: make(chan StatusUpdate, 1),
	}
}

// dataMutex should be taken by the caller
func (fbsk *folderBranchStatusKeeper) signalChangeLocked() {
	fbsk.updateMutex.Lock()
	defer fbsk.updateMutex.Unlock()
	close(fbsk.updateChan)
	fbsk.updateChan = make(chan StatusUpdate, 1)
}

// setRootMetadata sets the current head metadata for the
// corresponding folder-branch.
func (fbsk *folderBranchStatusKeeper) setRootMetadata(md ImmutableRootMetadata) {
	fbsk.dataMutex.Lock()
	defer fbsk.dataMutex.Unlock()
	if fbsk.md == md {
		return
	}
	fbsk.md = md
	fbsk.signalChangeLocked()
}

func (fbsk *folderBranchStatusKeeper) setCRSummary(unmerged []*crChainSummary,
	merged []*crChainSummary) {
	fbsk.dataMutex.Lock()
	defer fbsk.dataMutex.Unlock()
	if reflect.DeepEqual(unmerged, fbsk.unmerged) &&
		reflect.DeepEqual(merged, fbsk.merged) {
		return
	}
	fbsk.unmerged = unmerged
	fbsk.merged = merged
	fbsk.signalChangeLocked()
}

func (fbsk *folderBranchStatusKeeper) addNode(m map[NodeID]Node, n Node) {
	fbsk.dataMutex.Lock()
	defer fbsk.dataMutex.Unlock()
	id := n.GetID()
	_, ok := m[id]
	if ok {
		return
	}
	m[id] = n
	fbsk.signalChangeLocked()
}

func (fbsk *folderBranchStatusKeeper) rmNode(m map[NodeID]Node, n Node) {
	fbsk.dataMutex.Lock()
	defer fbsk.dataMutex.Unlock()
	id := n.GetID()
	_, ok := m[id]
	if !ok {
		return
	}
	delete(m, id)
	fbsk.signalChangeLocked()
}

func (fbsk *folderBranchStatusKeeper) addDirtyNode(n Node) {
	fbsk.addNode(fbsk.dirtyNodes, n)
}

func (fbsk *folderBranchStatusKeeper) rmDirtyNode(n Node) {
	fbsk.rmNode(fbsk.dirtyNodes, n)
}

// dataMutex should be taken by the caller
func (fbsk *folderBranchStatusKeeper) convertNodesToPathsLocked(
	m map[NodeID]Node) []string {
	var ret []string
	for _, n := range m {
		ret = append(ret, fbsk.nodeCache.PathFromNode(n).String())
	}
	return ret
}

// getStatus returns a FolderBranchStatus-representation of the
// current status. The returned channel is closed whenever the status
// changes, except for journal status changes.
func (fbsk *folderBranchStatusKeeper) getStatus(ctx context.Context) (
	FolderBranchStatus, <-chan StatusUpdate, error) {
	fbsk.dataMutex.Lock()
	defer fbsk.dataMutex.Unlock()
	fbsk.updateMutex.Lock()
	defer fbsk.updateMutex.Unlock()

	var fbs FolderBranchStatus

	if fbsk.md != (ImmutableRootMetadata{}) {
		fbs.Staged = fbsk.md.IsUnmergedSet()
		fbs.BranchID = fbsk.md.BID().String()
		name, err := fbsk.config.KBPKI().GetNormalizedUsername(ctx, fbsk.md.LastModifyingWriter())
		if err != nil {
			return FolderBranchStatus{}, nil, err
		}
		fbs.HeadWriter = name
		fbs.DiskUsage = fbsk.md.DiskUsage()
		fbs.RekeyPending = fbsk.config.RekeyQueue().IsRekeyPending(fbsk.md.TlfID())
		fbs.FolderID = fbsk.md.TlfID().String()
		fbs.Revision = fbsk.md.Revision()

		// TODO: Ideally, the journal would push status
		// updates to this object instead, so we can notify
		// listeners.
		jServer, err := GetJournalServer(fbsk.config)
		if err == nil {
			jStatus, err := jServer.JournalStatus(fbsk.md.TlfID())
			if err != nil {
				log := fbsk.config.MakeLogger("")
				log.CWarningf(ctx, "Error getting journal status for %s: %v", fbsk.md.TlfID(), err)
			} else {
				fbs.Journal = &jStatus
			}
		}
	}

	fbs.DirtyPaths = fbsk.convertNodesToPathsLocked(fbsk.dirtyNodes)

	fbs.Unmerged = fbsk.unmerged
	fbs.Merged = fbsk.merged

	return fbs, fbsk.updateChan, nil
}
<commit_msg>Expose latest key generaion in the status file<commit_after>// Copyright 2016 Keybase Inc. All rights reserved.
// Use of this source code is governed by a BSD
// license that can be found in the LICENSE file.

package libkbfs

import (
	"reflect"
	"sync"

	"github.com/keybase/client/go/libkb"

	"golang.org/x/net/context"
)

// FolderBranchStatus is a simple data structure describing the
// current status of a particular folder-branch.  It is suitable for
// encoding directly as JSON.
type FolderBranchStatus struct {
	Staged              bool
	BranchID            string
	HeadWriter          libkb.NormalizedUsername
	DiskUsage           uint64
	RekeyPending        bool
	LatestKeyGeneration KeyGen
	FolderID            string
	Revision            MetadataRevision

	// DirtyPaths are files that have been written, but not flushed.
	// They do not represent unstaged changes in your local instance.
	DirtyPaths []string

	// If we're in the staged state, these summaries show the
	// diverging operations per-file
	Unmerged []*crChainSummary
	Merged   []*crChainSummary

	Journal *TLFJournalStatus `json:",omitempty"`
}

// KBFSStatus represents the content of the top-level status file. It is
// suitable for encoding directly as JSON.
// TODO: implement magical status update like FolderBranchStatus
type KBFSStatus struct {
	CurrentUser     string
	IsConnected     bool
	UsageBytes      int64
	LimitBytes      int64
	FailingServices map[string]error
	JournalServer   *JournalServerStatus `json:",omitempty"`
}

// StatusUpdate is a dummy type used to indicate status has been updated.
type StatusUpdate struct{}

// folderBranchStatusKeeper holds and updates the status for a given
// folder-branch, and produces FolderBranchStatus instances suitable
// for callers outside this package to consume.
type folderBranchStatusKeeper struct {
	config    Config
	nodeCache NodeCache

	md         ImmutableRootMetadata
	dirtyNodes map[NodeID]Node
	unmerged   []*crChainSummary
	merged     []*crChainSummary
	dataMutex  sync.Mutex

	updateChan  chan StatusUpdate
	updateMutex sync.Mutex
}

func newFolderBranchStatusKeeper(
	config Config, nodeCache NodeCache) *folderBranchStatusKeeper {
	return &folderBranchStatusKeeper{
		config:     config,
		nodeCache:  nodeCache,
		dirtyNodes: make(map[NodeID]Node),
		updateChan: make(chan StatusUpdate, 1),
	}
}

// dataMutex should be taken by the caller
func (fbsk *folderBranchStatusKeeper) signalChangeLocked() {
	fbsk.updateMutex.Lock()
	defer fbsk.updateMutex.Unlock()
	close(fbsk.updateChan)
	fbsk.updateChan = make(chan StatusUpdate, 1)
}

// setRootMetadata sets the current head metadata for the
// corresponding folder-branch.
func (fbsk *folderBranchStatusKeeper) setRootMetadata(md ImmutableRootMetadata) {
	fbsk.dataMutex.Lock()
	defer fbsk.dataMutex.Unlock()
	if fbsk.md == md {
		return
	}
	fbsk.md = md
	fbsk.signalChangeLocked()
}

func (fbsk *folderBranchStatusKeeper) setCRSummary(unmerged []*crChainSummary,
	merged []*crChainSummary) {
	fbsk.dataMutex.Lock()
	defer fbsk.dataMutex.Unlock()
	if reflect.DeepEqual(unmerged, fbsk.unmerged) &&
		reflect.DeepEqual(merged, fbsk.merged) {
		return
	}
	fbsk.unmerged = unmerged
	fbsk.merged = merged
	fbsk.signalChangeLocked()
}

func (fbsk *folderBranchStatusKeeper) addNode(m map[NodeID]Node, n Node) {
	fbsk.dataMutex.Lock()
	defer fbsk.dataMutex.Unlock()
	id := n.GetID()
	_, ok := m[id]
	if ok {
		return
	}
	m[id] = n
	fbsk.signalChangeLocked()
}

func (fbsk *folderBranchStatusKeeper) rmNode(m map[NodeID]Node, n Node) {
	fbsk.dataMutex.Lock()
	defer fbsk.dataMutex.Unlock()
	id := n.GetID()
	_, ok := m[id]
	if !ok {
		return
	}
	delete(m, id)
	fbsk.signalChangeLocked()
}

func (fbsk *folderBranchStatusKeeper) addDirtyNode(n Node) {
	fbsk.addNode(fbsk.dirtyNodes, n)
}

func (fbsk *folderBranchStatusKeeper) rmDirtyNode(n Node) {
	fbsk.rmNode(fbsk.dirtyNodes, n)
}

// dataMutex should be taken by the caller
func (fbsk *folderBranchStatusKeeper) convertNodesToPathsLocked(
	m map[NodeID]Node) []string {
	var ret []string
	for _, n := range m {
		ret = append(ret, fbsk.nodeCache.PathFromNode(n).String())
	}
	return ret
}

// getStatus returns a FolderBranchStatus-representation of the
// current status. The returned channel is closed whenever the status
// changes, except for journal status changes.
func (fbsk *folderBranchStatusKeeper) getStatus(ctx context.Context) (
	FolderBranchStatus, <-chan StatusUpdate, error) {
	fbsk.dataMutex.Lock()
	defer fbsk.dataMutex.Unlock()
	fbsk.updateMutex.Lock()
	defer fbsk.updateMutex.Unlock()

	var fbs FolderBranchStatus

	if fbsk.md != (ImmutableRootMetadata{}) {
		fbs.Staged = fbsk.md.IsUnmergedSet()
		fbs.BranchID = fbsk.md.BID().String()
		name, err := fbsk.config.KBPKI().GetNormalizedUsername(ctx, fbsk.md.LastModifyingWriter())
		if err != nil {
			return FolderBranchStatus{}, nil, err
		}
		fbs.HeadWriter = name
		fbs.DiskUsage = fbsk.md.DiskUsage()
		fbs.RekeyPending = fbsk.config.RekeyQueue().IsRekeyPending(fbsk.md.TlfID())
		fbs.LatestKeyGeneration = fbsk.md.LatestKeyGeneration()
		fbs.FolderID = fbsk.md.TlfID().String()
		fbs.Revision = fbsk.md.Revision()

		// TODO: Ideally, the journal would push status
		// updates to this object instead, so we can notify
		// listeners.
		jServer, err := GetJournalServer(fbsk.config)
		if err == nil {
			jStatus, err := jServer.JournalStatus(fbsk.md.TlfID())
			if err != nil {
				log := fbsk.config.MakeLogger("")
				log.CWarningf(ctx, "Error getting journal status for %s: %v", fbsk.md.TlfID(), err)
			} else {
				fbs.Journal = &jStatus
			}
		}
	}

	fbs.DirtyPaths = fbsk.convertNodesToPathsLocked(fbsk.dirtyNodes)

	fbs.Unmerged = fbsk.unmerged
	fbs.Merged = fbsk.merged

	return fbs, fbsk.updateChan, nil
}
<|endoftext|>