<commit_before>package azurerm

import (
	"fmt"
	"log"
	"net/http"
	"time"

	"bytes"

	"github.com/Azure/azure-sdk-for-go/arm/web"
	"github.com/hashicorp/terraform/helper/hashcode"
	"github.com/hashicorp/terraform/helper/resource"
	"github.com/hashicorp/terraform/helper/schema"
)

func resourceArmAppServicePlan() *schema.Resource {
	return &schema.Resource{
		Create: resourceArmAppServicePlanCreateUpdate,
		Read:   resourceArmAppServicePlanRead,
		Update: resourceArmAppServicePlanCreateUpdate,
		Delete: resourceArmAppServicePlanDelete,
		Importer: &schema.ResourceImporter{
			State: schema.ImportStatePassthrough,
		},

		Schema: map[string]*schema.Schema{
			"resource_group_name": {
				Type:     schema.TypeString,
				Required: true,
				ForceNew: true,
			},
			"name": {
				Type:     schema.TypeString,
				Required: true,
				ForceNew: true,
			},
			"location": locationSchema(),
			"sku": {
				Type:     schema.TypeSet,
				Required: true,
				MaxItems: 1,
				Elem: &schema.Resource{
					Schema: map[string]*schema.Schema{
						"tier": {
							Type:     schema.TypeString,
							Required: true,
						},
						"size": {
							Type:     schema.TypeString,
							Required: true,
						},
					},
				},
				Set: resourceAzureRMAppServicePlanSkuHash,
			},
			"maximum_number_of_workers": {
				Type:     schema.TypeInt,
				Optional: true,
				Computed: true,
			},
			"tags": tagsSchema(),
		},
	}
}

func resourceArmAppServicePlanCreateUpdate(d *schema.ResourceData, meta interface{}) error {
	client := meta.(*ArmClient)
	AppServicePlanClient := client.appServicePlansClient

	log.Printf("[INFO] preparing arguments for AzureRM App Service Plan creation.")

	resGroup := d.Get("resource_group_name").(string)
	name := d.Get("name").(string)
	location := d.Get("location").(string)
	tags := d.Get("tags").(map[string]interface{})

	sku := expandAzureRmAppServicePlanSku(d)

	properties := web.AppServicePlanProperties{}
	if v, ok := d.GetOk("maximum_number_of_workers"); ok {
		maximumNumberOfWorkers := int32(v.(int))
		properties.MaximumNumberOfWorkers = &maximumNumberOfWorkers
	}

	appServicePlan := web.AppServicePlan{
		Location:                 &location,
		AppServicePlanProperties: &properties,
		Tags: expandTags(tags),
		Sku:  &sku,
	}

	_, error := AppServicePlanClient.CreateOrUpdate(resGroup, name, appServicePlan, make(chan struct{}))
	err := <-error
	if err != nil {
		return err
	}

	read, err := AppServicePlanClient.Get(resGroup, name)
	if err != nil {
		return err
	}
	if read.ID == nil {
		return fmt.Errorf("Cannot read AzureRM App Service Plan %s (resource group %s) ID", name, resGroup)
	}

	d.SetId(*read.ID)

	log.Printf("[DEBUG] Waiting for App Service Plan (%s) to become available", name)
	stateConf := &resource.StateChangeConf{
		Pending: []string{"Accepted", "Updating"},
		Target:  []string{"Succeeded"},
		Refresh: appServicePlanStateRefreshFunc(client, resGroup, name),
		Timeout: 10 * time.Minute,
	}
	if _, err := stateConf.WaitForState(); err != nil {
		return fmt.Errorf("Error waiting for App Service Plan (%s) to become available: %+v", name, err)
	}

	return resourceArmAppServicePlanRead(d, meta)
}

func resourceArmAppServicePlanRead(d *schema.ResourceData, meta interface{}) error {
	AppServicePlanClient := meta.(*ArmClient).appServicePlansClient

	id, err := parseAzureResourceID(d.Id())
	if err != nil {
		return err
	}

	log.Printf("[DEBUG] Reading Azure App Service Plan %s", id)

	resGroup := id.ResourceGroup
	name := id.Path["serverfarms"]

	resp, err := AppServicePlanClient.Get(resGroup, name)
	if err != nil {
		if resp.StatusCode == http.StatusNotFound {
			d.SetId("")
			return nil
		}
		return fmt.Errorf("Error making Read request on Azure App Service Plan %s: %s", name, err)
	}

	d.Set("name", name)
	d.Set("resource_group_name", resGroup)
	d.Set("location", azureRMNormalizeLocation(*resp.Location))

	if props := resp.AppServicePlanProperties; props != nil {
		d.Set("maximum_number_of_workers", props.MaximumNumberOfWorkers)
	}

	sku := flattenAzureRmAppServicePlanSku(*resp.Sku)
	d.Set("sku", &sku)

	return nil
}

func resourceArmAppServicePlanDelete(d *schema.ResourceData, meta interface{}) error {
	AppServicePlanClient := meta.(*ArmClient).appServicePlansClient

	id, err := parseAzureResourceID(d.Id())
	if err != nil {
		return err
	}
	resGroup := id.ResourceGroup
	name := id.Path["serverfarms"]

	log.Printf("[DEBUG] Deleting app service plan %s: %s", resGroup, name)

	_, err = AppServicePlanClient.Delete(resGroup, name)

	return err
}

func resourceAzureRMAppServicePlanSkuHash(v interface{}) int {
	var buf bytes.Buffer
	m := v.(map[string]interface{})

	tier := m["tier"].(string)
	size := m["size"].(string)

	buf.WriteString(fmt.Sprintf("%s-", tier))
	buf.WriteString(fmt.Sprintf("%s-", size))

	return hashcode.String(buf.String())
}

func expandAzureRmAppServicePlanSku(d *schema.ResourceData) web.SkuDescription {
	configs := d.Get("sku").(*schema.Set).List()
	config := configs[0].(map[string]interface{})

	tier := config["tier"].(string)
	size := config["size"].(string)

	sku := web.SkuDescription{
		Name: &size,
		Tier: &tier,
		Size: &size,
	}

	return sku
}

func flattenAzureRmAppServicePlanSku(profile web.SkuDescription) *schema.Set {
	skus := &schema.Set{
		F: resourceAzureRMAppServicePlanSkuHash,
	}

	sku := make(map[string]interface{}, 2)

	sku["tier"] = *profile.Tier
	sku["size"] = *profile.Size

	skus.Add(sku)

	return skus
}

func appServicePlanStateRefreshFunc(client *ArmClient, resourceGroupName string, name string) resource.StateRefreshFunc {
	return func() (interface{}, string, error) {
		res, err := client.appServicePlansClient.Get(resourceGroupName, name)
		if err != nil {
			return nil, "", fmt.Errorf("Error issuing read request in appServicePlanStateRefreshFunc to Azure ARM for App Service Plan '%s' (RG: '%s'): %+v", name, resourceGroupName, err)
		}

		return res, string(res.AppServicePlanProperties.ProvisioningState), nil
	}
}
<commit_msg>setting tags<commit_after>package azurerm

import (
	"fmt"
	"log"
	"net/http"
	"time"

	"bytes"

	"github.com/Azure/azure-sdk-for-go/arm/web"
	"github.com/hashicorp/terraform/helper/hashcode"
	"github.com/hashicorp/terraform/helper/resource"
	"github.com/hashicorp/terraform/helper/schema"
)

func resourceArmAppServicePlan() *schema.Resource {
	return &schema.Resource{
		Create: resourceArmAppServicePlanCreateUpdate,
		Read:   resourceArmAppServicePlanRead,
		Update: resourceArmAppServicePlanCreateUpdate,
		Delete: resourceArmAppServicePlanDelete,
		Importer: &schema.ResourceImporter{
			State: schema.ImportStatePassthrough,
		},

		Schema: map[string]*schema.Schema{
			"resource_group_name": {
				Type:     schema.TypeString,
				Required: true,
				ForceNew: true,
			},
			"name": {
				Type:     schema.TypeString,
				Required: true,
				ForceNew: true,
			},
			"location": locationSchema(),
			"sku": {
				Type:     schema.TypeSet,
				Required: true,
				MaxItems: 1,
				Elem: &schema.Resource{
					Schema: map[string]*schema.Schema{
						"tier": {
							Type:     schema.TypeString,
							Required: true,
						},
						"size": {
							Type:     schema.TypeString,
							Required: true,
						},
					},
				},
				Set: resourceAzureRMAppServicePlanSkuHash,
			},
			"maximum_number_of_workers": {
				Type:     schema.TypeInt,
				Optional: true,
				Computed: true,
			},
			"tags": tagsSchema(),
		},
	}
}

func resourceArmAppServicePlanCreateUpdate(d *schema.ResourceData, meta interface{}) error {
	client := meta.(*ArmClient)
	AppServicePlanClient := client.appServicePlansClient

	log.Printf("[INFO] preparing arguments for AzureRM App Service Plan creation.")

	resGroup := d.Get("resource_group_name").(string)
	name := d.Get("name").(string)
	location := d.Get("location").(string)
	tags := d.Get("tags").(map[string]interface{})

	sku := expandAzureRmAppServicePlanSku(d)

	properties := web.AppServicePlanProperties{}
	if v, ok := d.GetOk("maximum_number_of_workers"); ok {
		maximumNumberOfWorkers := int32(v.(int))
		properties.MaximumNumberOfWorkers = &maximumNumberOfWorkers
	}

	appServicePlan := web.AppServicePlan{
		Location:                 &location,
		AppServicePlanProperties: &properties,
		Tags: expandTags(tags),
		Sku:  &sku,
	}

	_, error := AppServicePlanClient.CreateOrUpdate(resGroup, name, appServicePlan, make(chan struct{}))
	err := <-error
	if err != nil {
		return err
	}

	read, err := AppServicePlanClient.Get(resGroup, name)
	if err != nil {
		return err
	}
	if read.ID == nil {
		return fmt.Errorf("Cannot read AzureRM App Service Plan %s (resource group %s) ID", name, resGroup)
	}

	d.SetId(*read.ID)

	log.Printf("[DEBUG] Waiting for App Service Plan (%s) to become available", name)
	stateConf := &resource.StateChangeConf{
		Pending: []string{"Accepted", "Updating"},
		Target:  []string{"Succeeded"},
		Refresh: appServicePlanStateRefreshFunc(client, resGroup, name),
		Timeout: 10 * time.Minute,
	}
	if _, err := stateConf.WaitForState(); err != nil {
		return fmt.Errorf("Error waiting for App Service Plan (%s) to become available: %+v", name, err)
	}

	return resourceArmAppServicePlanRead(d, meta)
}

func resourceArmAppServicePlanRead(d *schema.ResourceData, meta interface{}) error {
	AppServicePlanClient := meta.(*ArmClient).appServicePlansClient

	id, err := parseAzureResourceID(d.Id())
	if err != nil {
		return err
	}

	log.Printf("[DEBUG] Reading Azure App Service Plan %s", id)

	resGroup := id.ResourceGroup
	name := id.Path["serverfarms"]

	resp, err := AppServicePlanClient.Get(resGroup, name)
	if err != nil {
		if resp.StatusCode == http.StatusNotFound {
			d.SetId("")
			return nil
		}
		return fmt.Errorf("Error making Read request on Azure App Service Plan %s: %s", name, err)
	}

	d.Set("name", name)
	d.Set("resource_group_name", resGroup)
	d.Set("location", azureRMNormalizeLocation(*resp.Location))

	if props := resp.AppServicePlanProperties; props != nil {
		d.Set("maximum_number_of_workers", props.MaximumNumberOfWorkers)
	}

	sku := flattenAzureRmAppServicePlanSku(*resp.Sku)
	d.Set("sku", &sku)

	flattenAndSetTags(d, resp.Tags)

	return nil
}

func resourceArmAppServicePlanDelete(d *schema.ResourceData, meta interface{}) error {
	AppServicePlanClient := meta.(*ArmClient).appServicePlansClient

	id, err := parseAzureResourceID(d.Id())
	if err != nil {
		return err
	}
	resGroup := id.ResourceGroup
	name := id.Path["serverfarms"]

	log.Printf("[DEBUG] Deleting app service plan %s: %s", resGroup, name)

	_, err = AppServicePlanClient.Delete(resGroup, name)

	return err
}

func resourceAzureRMAppServicePlanSkuHash(v interface{}) int {
	var buf bytes.Buffer
	m := v.(map[string]interface{})

	tier := m["tier"].(string)
	size := m["size"].(string)

	buf.WriteString(fmt.Sprintf("%s-", tier))
	buf.WriteString(fmt.Sprintf("%s-", size))

	return hashcode.String(buf.String())
}

func expandAzureRmAppServicePlanSku(d *schema.ResourceData) web.SkuDescription {
	configs := d.Get("sku").(*schema.Set).List()
	config := configs[0].(map[string]interface{})

	tier := config["tier"].(string)
	size := config["size"].(string)

	sku := web.SkuDescription{
		Name: &size,
		Tier: &tier,
		Size: &size,
	}

	return sku
}

func flattenAzureRmAppServicePlanSku(profile web.SkuDescription) *schema.Set {
	skus := &schema.Set{
		F: resourceAzureRMAppServicePlanSkuHash,
	}

	sku := make(map[string]interface{}, 2)

	sku["tier"] = *profile.Tier
	sku["size"] = *profile.Size

	skus.Add(sku)

	return skus
}

func appServicePlanStateRefreshFunc(client *ArmClient, resourceGroupName string, name string) resource.StateRefreshFunc {
	return func() (interface{}, string, error) {
		res, err := client.appServicePlansClient.Get(resourceGroupName, name)
		if err != nil {
			return nil, "", fmt.Errorf("Error issuing read request in appServicePlanStateRefreshFunc to Azure ARM for App Service Plan '%s' (RG: '%s'): %+v", name, resourceGroupName, err)
		}

		return res, string(res.AppServicePlanProperties.ProvisioningState), nil
	}
}
<|endoftext|>


<commit_before>// Copyright (c) 2016 Uber Technologies, Inc.
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.

package cpustat

import (
	"bytes"
	"log"
	"os"
	"strconv"
	"strings"
)

// crude protection against rollover. This will miss the last portion of the previous sample
// before the overflow, but capturing that is complicated because of the various number types
// involved and their inconsistent documentation.
func SafeSub(a, b uint64) uint64 {
	if a < b {
		return a
	}
	return a - b
}

func SafeSubFloat(a, b float64) float64 {
	if a < b {
		return a
	}
	return a - b
}

func ScaledSub(cur, prev uint64, scale float64) uint64 {
	return uint64((float64(SafeSub(cur, prev)) * scale) + 0.5)
}

// note that this is not thread safe
var buf *bytes.Buffer

// ReadSmallFile is like os.ReadFile but dangerously optimized for reading files from /proc.
// The file is not statted first, and the same buffer is used every time.
func ReadSmallFile(filename string) ([]byte, error) {
	f, err := os.Open(filename)
	if err != nil {
		f.Close()
		return nil, err
	}

	if buf == nil {
		buf = bytes.NewBuffer(make([]byte, 0, 8192))
	} else {
		buf.Reset()
	}
	_, err = buf.ReadFrom(f)
	f.Close()
	return buf.Bytes(), err
}

// Read a small file and split on newline
func ReadFileLines(filename string) ([]string, error) {
	file, err := ReadSmallFile(filename)
	if err != nil {
		return nil, err
	}

	// TODO - these next two lines cause more GC than I expected
	fileStr := strings.TrimSpace(string(file))
	return strings.Split(fileStr, "\n"), nil
}

// pull a float64 out of a string
func ReadFloat(str string) float64 {
	val, err := strconv.ParseFloat(str, 64)
	if err != nil {
		log.Fatal(err)

	}
	return val
}

// pull a uint64 out of a string
func ReadUInt(str string) uint64 {
	val, err := strconv.ParseUint(str, 10, 64)
	if err != nil {
		panic(err)
	}
	return val
}

// pull a int64 out of a string
func ReadInt(str string) int64 {
	val, err := strconv.ParseInt(str, 10, 64)
	if err != nil {
		log.Fatal(err)
	}
	return val
}

// remove grouping characters that confuse the termui parser
func StripSpecial(r rune) rune {
	if r == '[' || r == ']' || r == '(' || r == ')' {
		return -1
	}
	return r
}
<commit_msg>Fix typo in util.go.<commit_after>// Copyright (c) 2016 Uber Technologies, Inc.
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.

package cpustat

import (
	"bytes"
	"log"
	"os"
	"strconv"
	"strings"
)

// crude protection against rollover. This will miss the last portion of the previous sample
// before the overflow, but capturing that is complicated because of the various number types
// involved and their inconsistent documentation.
func SafeSub(a, b uint64) uint64 {
	if a < b {
		return a
	}
	return a - b
}

func SafeSubFloat(a, b float64) float64 {
	if a < b {
		return a
	}
	return a - b
}

func ScaledSub(cur, prev uint64, scale float64) uint64 {
	return uint64((float64(SafeSub(cur, prev)) * scale) + 0.5)
}

// note that this is not thread safe
var buf *bytes.Buffer

// ReadSmallFile is like os.ReadFile but dangerously optimized for reading files from /proc.
// The file is not statted first, and the same buffer is used every time.
func ReadSmallFile(filename string) ([]byte, error) {
	f, err := os.Open(filename)
	if err != nil {
		f.Close()
		return nil, err
	}

	if buf == nil {
		buf = bytes.NewBuffer(make([]byte, 0, 8192))
	} else {
		buf.Reset()
	}
	_, err = buf.ReadFrom(f)
	f.Close()
	return buf.Bytes(), err
}

// Read a small file and split on newline
func ReadFileLines(filename string) ([]string, error) {
	file, err := ReadSmallFile(filename)
	if err != nil {
		return nil, err
	}

	// TODO - these next two lines cause more GC than I expected
	fileStr := strings.TrimSpace(string(file))
	return strings.Split(fileStr, "\n"), nil
}

// pull a float64 out of a string
func ReadFloat(str string) float64 {
	val, err := strconv.ParseFloat(str, 64)
	if err != nil {
		log.Fatal(err)

	}
	return val
}

// pull a uint64 out of a string
func ReadUInt(str string) uint64 {
	val, err := strconv.ParseUint(str, 10, 64)
	if err != nil {
		panic(err)
	}
	return val
}

// pull an int64 out of a string
func ReadInt(str string) int64 {
	val, err := strconv.ParseInt(str, 10, 64)
	if err != nil {
		log.Fatal(err)
	}
	return val
}

// remove grouping characters that confuse the termui parser
func StripSpecial(r rune) rune {
	if r == '[' || r == ']' || r == '(' || r == ')' {
		return -1
	}
	return r
}
<|endoftext|>


<commit_before>package main

import (
	// "encoding/base64"
	"errors"
	"fmt"
	"strings"
	"strconv"
	"encoding/json"
	"github.com/hyperledger/fabric/core/chaincode/shim"
	"github.com/hyperledger/fabric/core/crypto/primitives"
)

type AssetManagementChaincode struct {
}
type Error struct{
  Err string
}
type Circle struct{
  Id string
  Owner string
  Radius string
}
func (t *AssetManagementChaincode) Init(stub shim.ChaincodeStubInterface, function string, args []string) ([]byte, error) {
  fmt.Println("Init Chaincode...")
	err := stub.CreateTable("AssetsOwnership", []*shim.ColumnDefinition{
		&shim.ColumnDefinition{Name: "Asset", Type: shim.ColumnDefinition_STRING, Key: true},
		&shim.ColumnDefinition{Name: "Owner", Type: shim.ColumnDefinition_BYTES, Key: false},
	})
	if err != nil {
		return nil, errors.New("Failed creating AssetsOnwership table.")
	}
  return nil,nil
}

func (t *AssetManagementChaincode) Invoke(stub shim.ChaincodeStubInterface, function string, args []string) ([]byte, error){
  fmt.Println("Invoke is invoking function "+function)

  if function == "createCircle"{
    return t.createCircle(stub,args)
  }
	// else if function == "createCircle"{
  //   return t.createCircle(stub,args)
  // }
  return nil,nil
}

func (t *AssetManagementChaincode) createCircle(stub shim.ChaincodeStubInterface, args []string) ([]byte, error){
  if len(args) != 3 {
    error := Error{"Incorrect number of arguments. Expecting 3"}
    errorMarshal, _ := json.Marshal(error)
    stub.SetEvent("createCircleError", errorMarshal)
    return nil, errors.New("Incorrect number of arguments. Expecting 3")
  }
  // ==== Input sanitation ====
  fmt.Println("- start createCircle")
  if len(args[0]) <= 0 {
    error := Error{"1st argument must be a non-empty string"}
    errorMarshal, _ := json.Marshal(error)
    stub.SetEvent("createCircleError", errorMarshal)
    return nil, errors.New("1st argument must be a non-empty string")
  }
  if len(args[1]) <= 0 {
    error := Error{"2nd argument must be a non-empty string"}
    errorMarshal, _ := json.Marshal(error)
    stub.SetEvent("createCircleError", errorMarshal)
    return nil, errors.New("2nd argument must be a non-empty string")
  }
  if len(args[2]) <= 0 {
    error := Error{"3rd argument must be a non-empty string"}
    errorMarshal, _ := json.Marshal(error)
    stub.SetEvent("createCircleError", errorMarshal)
    return nil, errors.New("3rd argument must be a non-empty string")
  }
	callerCert, err := stub.GetCallerMetadata()
	if err != nil {
		fmt.Println("Failed getting metadata")
		return nil, errors.New("Failed getting metadata.")
	}
	payload, err := stub.GetPayload()
	if err != nil {
		return nil, errors.New("Failed getting payload")
	}
	binding, err := stub.GetBinding()
	if err != nil {
		return nil, errors.New("Failed getting binding")
	}
  cc := convert(callerCert[:])
	p := convert(payload[:])
	b := convert(binding[:])

	if len(callerCert) == 0 {
		fmt.Println("Invalid caller certificate. Empty.")
		return nil, errors.New(cc+p+b)
	}

	fmt.Println("The caller is [%x]", callerCert)

	id:= args[0]
	owner:= args[1]
	radius:= args[2]

	assestAsJson,err := stub.GetState(id)

	if len(assestAsJson)>=0{
		fmt.Println("Asset already exists")
		return nil, errors.New("Cant create asset already exists")
	}

	var c Circle
	c = Circle{id,owner,radius}
	assestAsJson,err = json.Marshal(c)
	stub.PutState(id,assestAsJson)
	return nil,nil
}

func (t *AssetManagementChaincode) Query(stub shim.ChaincodeStubInterface, function string, args []string) ([]byte,error) {
    fmt.Println("Query is running " + function)

    if function =="getCircle"{
		return t.getCircle(stub,args)
	}
	return nil,errors.New("Received unknown function query")
}

func (t *AssetManagementChaincode) getCircle(stub shim.ChaincodeStubInterface, args []string) ([]byte,error) {
	fmt.Println("getCircle called")
	if len(args) !=1{
		return nil,errors.New("Incorrect number of arguments. Expecting 1")
	}
	Id := args[0]
	circle, err := stub.GetState(Id)
	if err != nil {
		return nil,err
	}

	return circle,nil
}
func convert( b []byte ) string {
    s := make([]string,len(b))
    for i := range b {
        s[i] = strconv.Itoa(int(b[i]))
    }
    return strings.Join(s,",")
}
func main() {
	primitives.SetSecurityLevel("SHA3", 256)
	err := shim.Start(new(AssetManagementChaincode))
	if err != nil {
		fmt.Printf("Error starting AssetManagementChaincode: %s", err)
	}
}
<commit_msg>logs for chaincode<commit_after>package main

import (
	// "encoding/base64"
	"errors"
	"fmt"
	"strings"
	"strconv"
	"encoding/json"
	"github.com/hyperledger/fabric/core/chaincode/shim"
	"github.com/hyperledger/fabric/core/crypto/primitives"
)

type AssetManagementChaincode struct {
}
type Error struct{
  Err string
}
type Circle struct{
  Id string
  Owner string
  Radius string
}
func (t *AssetManagementChaincode) Init(stub shim.ChaincodeStubInterface, function string, args []string) ([]byte, error) {
  fmt.Println("Init Chaincode...")
	err := stub.CreateTable("AssetsOwnership", []*shim.ColumnDefinition{
		&shim.ColumnDefinition{Name: "Asset", Type: shim.ColumnDefinition_STRING, Key: true},
		&shim.ColumnDefinition{Name: "Owner", Type: shim.ColumnDefinition_BYTES, Key: false},
	})
	if err != nil {
		return nil, errors.New("Failed creating AssetsOnwership table.")
	}
  return nil,nil
}

func (t *AssetManagementChaincode) Invoke(stub shim.ChaincodeStubInterface, function string, args []string) ([]byte, error){
  fmt.Println("Invoke is invoking function "+function)

  if function == "createCircle"{
    return t.createCircle(stub,args)
  }
	// else if function == "createCircle"{
  //   return t.createCircle(stub,args)
  // }
  return nil,nil
}

func (t *AssetManagementChaincode) createCircle(stub shim.ChaincodeStubInterface, args []string) ([]byte, error){
  if len(args) != 3 {
    error := Error{"Incorrect number of arguments. Expecting 3"}
    errorMarshal, _ := json.Marshal(error)
    stub.SetEvent("createCircleError", errorMarshal)
    return nil, errors.New("Incorrect number of arguments. Expecting 3")
  }
  // ==== Input sanitation ====
  fmt.Println("- start createCircle")
  if len(args[0]) <= 0 {
    error := Error{"1st argument must be a non-empty string"}
    errorMarshal, _ := json.Marshal(error)
    stub.SetEvent("createCircleError", errorMarshal)
    return nil, errors.New("1st argument must be a non-empty string")
  }
  if len(args[1]) <= 0 {
    error := Error{"2nd argument must be a non-empty string"}
    errorMarshal, _ := json.Marshal(error)
    stub.SetEvent("createCircleError", errorMarshal)
    return nil, errors.New("2nd argument must be a non-empty string")
  }
  if len(args[2]) <= 0 {
    error := Error{"3rd argument must be a non-empty string"}
    errorMarshal, _ := json.Marshal(error)
    stub.SetEvent("createCircleError", errorMarshal)
    return nil, errors.New("3rd argument must be a non-empty string")
  }
	callerCert, err := stub.GetCallerMetadata()
	if err != nil {
		fmt.Println("Failed getting metadata")
		return nil, errors.New("Failed getting metadata.")
	}
	payload, err := stub.GetPayload()
	if err != nil {
		return nil, errors.New("Failed getting payload")
	}
	binding, err := stub.GetBinding()
	if err != nil {
		return nil, errors.New("Failed getting binding")
	}
  cc := convert(callerCert[:])
	p := convert(payload[:])
	b := convert(binding[:])

	if len(callerCert) == 0 {
		fmt.Println("Invalid caller certificate. Empty.")
		return nil, errors.New("this is error..."+cc+p+b)
	}

	fmt.Println("The caller is [%x]", callerCert)

	id:= args[0]
	owner:= args[1]
	radius:= args[2]

	assestAsJson,err := stub.GetState(id)

	if len(assestAsJson)>=0{
		fmt.Println("Asset already exists")
		return nil, errors.New("Cant create asset already exists")
	}

	var c Circle
	c = Circle{id,owner,radius}
	assestAsJson,err = json.Marshal(c)
	stub.PutState(id,assestAsJson)
	return nil,nil
}

func (t *AssetManagementChaincode) Query(stub shim.ChaincodeStubInterface, function string, args []string) ([]byte,error) {
    fmt.Println("Query is running " + function)

    if function =="getCircle"{
		return t.getCircle(stub,args)
	}
	return nil,errors.New("Received unknown function query")
}

func (t *AssetManagementChaincode) getCircle(stub shim.ChaincodeStubInterface, args []string) ([]byte,error) {
	fmt.Println("getCircle called")
	if len(args) !=1{
		return nil,errors.New("Incorrect number of arguments. Expecting 1")
	}
	Id := args[0]
	circle, err := stub.GetState(Id)
	if err != nil {
		return nil,err
	}

	return circle,nil
}
func convert( b []byte ) string {
    s := make([]string,len(b))
    for i := range b {
        s[i] = strconv.Itoa(int(b[i]))
    }
    return strings.Join(s,",")
}
func main() {
	primitives.SetSecurityLevel("SHA3", 256)
	err := shim.Start(new(AssetManagementChaincode))
	if err != nil {
		fmt.Printf("Error starting AssetManagementChaincode: %s", err)
	}
}
<|endoftext|>


<commit_before>// Copyright ©2014 The gonum Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

// Package fd provides functions to approximate derivatives using finite differences.
package fd

import (
	"math"
	"runtime"
	"sync"

	"github.com/gonum/floats"
)

// A Point is a stencil location in a finite difference formula.
type Point struct {
	Loc   float64
	Coeff float64
}

// Formula represents a finite difference formula on a regularly spaced grid
// that approximates the derivative of order k of a function f at x as
//  d^k f(x) ≈ (1 / Step^k) * \sum_i Coeff_i * f(x + Step * Loc_i).
type Formula struct {
	// Stencil is the set of sampling Points which are used to estimate the
	// derivative. The locations will be scaled by Step and are relative to x.
	Stencil    []Point
	Derivative int     // The order of the approximated derivative.
	Step       float64 // Default step size for the formula.
}

func (f Formula) isZero() bool {
	return f.Stencil == nil && f.Derivative == 0 && f.Step == 0
}

// Settings is the settings structure for computing finite differences.
type Settings struct {
	// Formula is the finite difference formula used
	// for approximating the derivative.
	// Zero value will default to the Central formula.
	Formula Formula
	// Step is the distance between points of the stencil.
	// If equal to 0, formula's default step will be used.
	Step float64

	OriginKnown bool    // Flag that the value at the origin x is known.
	OriginValue float64 // Value at the origin (only used if OriginKnown is true).

	Concurrent bool // Should the function calls be executed concurrently.
}

// Derivative estimates the derivative of the function f at the given location.
// The finite difference formula, the step size, and other options are
// specified by settings. If settings is nil, the first derivative will be
// estimated using the Central formula and a default step size.
func Derivative(f func(float64) float64, x float64, settings *Settings) float64 {
	if settings == nil {
		settings = &Settings{}
	}
	formula := settings.Formula
	if formula.isZero() {
		formula = Central
	}
	if formula.Derivative == 0 || formula.Stencil == nil || formula.Step == 0 {
		panic("fd: bad formula")
	}
	step := settings.Step
	if step == 0 {
		step = formula.Step
	}

	var deriv float64
	if !settings.Concurrent || runtime.GOMAXPROCS(0) == 1 {
		for _, pt := range formula.Stencil {
			if settings.OriginKnown && pt.Loc == 0 {
				deriv += pt.Coeff * settings.OriginValue
				continue
			}
			deriv += pt.Coeff * f(x+step*pt.Loc)
		}
		return deriv / math.Pow(step, float64(formula.Derivative))
	}

	wg := &sync.WaitGroup{}
	mux := &sync.Mutex{}
	for _, pt := range formula.Stencil {
		if settings.OriginKnown && pt.Loc == 0 {
			mux.Lock()
			deriv += pt.Coeff * settings.OriginValue
			mux.Unlock()
			continue
		}
		wg.Add(1)
		go func(pt Point) {
			defer wg.Done()
			fofx := f(x + step*pt.Loc)
			mux.Lock()
			defer mux.Unlock()
			deriv += pt.Coeff * fofx
		}(pt)
	}
	wg.Wait()
	return deriv / math.Pow(step, float64(formula.Derivative))
}

// Gradient estimates the gradient of the multivariate function f at the
// location x. The result is stored in-place into dst if dst is not nil,
// otherwise a new slice will be allocated and returned. Finite difference
// kernel and other options are specified by settings. If settings is nil,
// default settings will be used.
// Gradient panics if the length of dst and x is not equal, or if the
// derivative order of the formula is not 1.
func Gradient(dst []float64, f func([]float64) float64, x []float64, settings *Settings) []float64 {
	if dst == nil {
		dst = make([]float64, len(x))
	}
	if len(dst) != len(x) {
		panic("fd: slice length mismatch")
	}
	if settings == nil {
		settings = &Settings{}
	}

	formula := settings.Formula
	if formula.isZero() {
		formula = Central
	}
	if formula.Derivative == 0 || formula.Stencil == nil || formula.Step == 0 {
		panic("fd: bad formula")
	}
	if formula.Derivative != 1 {
		panic("fd: invalid derivative order")
	}

	step := settings.Step
	if step == 0 {
		step = formula.Step
	}

	expect := len(formula.Stencil) * len(x)
	nWorkers := 1
	if settings.Concurrent {
		nWorkers = runtime.GOMAXPROCS(0)
		if nWorkers > expect {
			nWorkers = expect
		}
	}

	if nWorkers == 1 {
		xcopy := make([]float64, len(x)) // So that x is not modified during the call.
		copy(xcopy, x)
		for i := range xcopy {
			var deriv float64
			for _, pt := range formula.Stencil {
				if settings.OriginKnown && pt.Loc == 0 {
					deriv += pt.Coeff * settings.OriginValue
					continue
				}
				xcopy[i] += pt.Loc * step
				deriv += pt.Coeff * f(xcopy)
				xcopy[i] = x[i]
			}
			dst[i] = deriv / step
		}
		return dst
	}

	sendChan := make(chan fdrun, expect)
	ansChan := make(chan fdrun, expect)
	quit := make(chan struct{})
	defer close(quit)

	// Launch workers. Workers receive an index and a step, and compute the answer.
	for i := 0; i < nWorkers; i++ {
		go func(sendChan <-chan fdrun, ansChan chan<- fdrun, quit <-chan struct{}) {
			xcopy := make([]float64, len(x))
			copy(xcopy, x)
			for {
				select {
				case <-quit:
					return
				case run := <-sendChan:
					xcopy[run.idx] += run.pt.Loc * step
					run.result = f(xcopy)
					xcopy[run.idx] = x[run.idx]
					ansChan <- run
				}
			}
		}(sendChan, ansChan, quit)
	}

	// Launch the distributor. Distributor sends the cases to be computed.
	go func(sendChan chan<- fdrun, ansChan chan<- fdrun) {
		for i := range x {
			for _, pt := range formula.Stencil {
				if settings.OriginKnown && pt.Loc == 0 {
					// Answer already known. Send the answer on the answer channel.
					ansChan <- fdrun{
						idx:    i,
						pt:     pt,
						result: settings.OriginValue,
					}
					continue
				}
				// Answer not known, send the answer to be computed.
				sendChan <- fdrun{
					idx: i,
					pt:  pt,
				}
			}
		}
	}(sendChan, ansChan)

	for i := range dst {
		dst[i] = 0
	}
	// Read in all of the results.
	for i := 0; i < expect; i++ {
		run := <-ansChan
		dst[run.idx] += run.pt.Coeff * run.result
	}
	floats.Scale(1/step, dst)
	return dst
}

type fdrun struct {
	idx    int
	pt     Point
	result float64
}

// Forward represents a first-order forward difference.
var Forward = Formula{
	Stencil:    []Point{{Loc: 0, Coeff: -1}, {Loc: 1, Coeff: 1}},
	Derivative: 1,
	Step:       1e-6,
}

// Backward represents a first-order backward difference.
var Backward = Formula{
	Stencil:    []Point{{Loc: -1, Coeff: -1}, {Loc: 0, Coeff: 1}},
	Derivative: 1,
	Step:       1e-6,
}

// Central represents a first-order central difference.
var Central = Formula{
	Stencil:    []Point{{Loc: -1, Coeff: -0.5}, {Loc: 1, Coeff: 0.5}},
	Derivative: 1,
	Step:       1e-6,
}

// Central2nd represents a secord-order central difference.
var Central2nd = Formula{
	Stencil:    []Point{{Loc: -1, Coeff: 1}, {Loc: 0, Coeff: -2}, {Loc: 1, Coeff: 1}},
	Derivative: 2,
	Step:       1e-3,
}
<commit_msg>Protect against user function modifying input slice.<commit_after>// Copyright ©2014 The gonum Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

// Package fd provides functions to approximate derivatives using finite differences.
package fd

import (
	"math"
	"runtime"
	"sync"

	"github.com/gonum/floats"
)

// A Point is a stencil location in a finite difference formula.
type Point struct {
	Loc   float64
	Coeff float64
}

// Formula represents a finite difference formula on a regularly spaced grid
// that approximates the derivative of order k of a function f at x as
//  d^k f(x) ≈ (1 / Step^k) * \sum_i Coeff_i * f(x + Step * Loc_i).
type Formula struct {
	// Stencil is the set of sampling Points which are used to estimate the
	// derivative. The locations will be scaled by Step and are relative to x.
	Stencil    []Point
	Derivative int     // The order of the approximated derivative.
	Step       float64 // Default step size for the formula.
}

func (f Formula) isZero() bool {
	return f.Stencil == nil && f.Derivative == 0 && f.Step == 0
}

// Settings is the settings structure for computing finite differences.
type Settings struct {
	// Formula is the finite difference formula used
	// for approximating the derivative.
	// Zero value will default to the Central formula.
	Formula Formula
	// Step is the distance between points of the stencil.
	// If equal to 0, formula's default step will be used.
	Step float64

	OriginKnown bool    // Flag that the value at the origin x is known.
	OriginValue float64 // Value at the origin (only used if OriginKnown is true).

	Concurrent bool // Should the function calls be executed concurrently.
}

// Derivative estimates the derivative of the function f at the given location.
// The finite difference formula, the step size, and other options are
// specified by settings. If settings is nil, the first derivative will be
// estimated using the Central formula and a default step size.
func Derivative(f func(float64) float64, x float64, settings *Settings) float64 {
	if settings == nil {
		settings = &Settings{}
	}
	formula := settings.Formula
	if formula.isZero() {
		formula = Central
	}
	if formula.Derivative == 0 || formula.Stencil == nil || formula.Step == 0 {
		panic("fd: bad formula")
	}
	step := settings.Step
	if step == 0 {
		step = formula.Step
	}

	var deriv float64
	if !settings.Concurrent || runtime.GOMAXPROCS(0) == 1 {
		for _, pt := range formula.Stencil {
			if settings.OriginKnown && pt.Loc == 0 {
				deriv += pt.Coeff * settings.OriginValue
				continue
			}
			deriv += pt.Coeff * f(x+step*pt.Loc)
		}
		return deriv / math.Pow(step, float64(formula.Derivative))
	}

	wg := &sync.WaitGroup{}
	mux := &sync.Mutex{}
	for _, pt := range formula.Stencil {
		if settings.OriginKnown && pt.Loc == 0 {
			mux.Lock()
			deriv += pt.Coeff * settings.OriginValue
			mux.Unlock()
			continue
		}
		wg.Add(1)
		go func(pt Point) {
			defer wg.Done()
			fofx := f(x + step*pt.Loc)
			mux.Lock()
			defer mux.Unlock()
			deriv += pt.Coeff * fofx
		}(pt)
	}
	wg.Wait()
	return deriv / math.Pow(step, float64(formula.Derivative))
}

// Gradient estimates the gradient of the multivariate function f at the
// location x. The result is stored in-place into dst if dst is not nil,
// otherwise a new slice will be allocated and returned. Finite difference
// kernel and other options are specified by settings. If settings is nil,
// default settings will be used.
// Gradient panics if the length of dst and x is not equal, or if the
// derivative order of the formula is not 1.
func Gradient(dst []float64, f func([]float64) float64, x []float64, settings *Settings) []float64 {
	if dst == nil {
		dst = make([]float64, len(x))
	}
	if len(dst) != len(x) {
		panic("fd: slice length mismatch")
	}
	if settings == nil {
		settings = &Settings{}
	}

	formula := settings.Formula
	if formula.isZero() {
		formula = Central
	}
	if formula.Derivative == 0 || formula.Stencil == nil || formula.Step == 0 {
		panic("fd: bad formula")
	}
	if formula.Derivative != 1 {
		panic("fd: invalid derivative order")
	}

	step := settings.Step
	if step == 0 {
		step = formula.Step
	}

	expect := len(formula.Stencil) * len(x)
	nWorkers := 1
	if settings.Concurrent {
		nWorkers = runtime.GOMAXPROCS(0)
		if nWorkers > expect {
			nWorkers = expect
		}
	}

	if nWorkers == 1 {
		xcopy := make([]float64, len(x)) // So that x is not modified during the call.
		for i := range xcopy {
			var deriv float64
			for _, pt := range formula.Stencil {
				if settings.OriginKnown && pt.Loc == 0 {
					deriv += pt.Coeff * settings.OriginValue
					continue
				}
				copy(xcopy, x)
				xcopy[i] += pt.Loc * step
				deriv += pt.Coeff * f(xcopy)
			}
			dst[i] = deriv / step
		}
		return dst
	}

	sendChan := make(chan fdrun, expect)
	ansChan := make(chan fdrun, expect)
	quit := make(chan struct{})
	defer close(quit)

	// Launch workers. Workers receive an index and a step, and compute the answer.
	for i := 0; i < nWorkers; i++ {
		go func(sendChan <-chan fdrun, ansChan chan<- fdrun, quit <-chan struct{}) {
			xcopy := make([]float64, len(x))
			for {
				select {
				case <-quit:
					return
				case run := <-sendChan:
					copy(xcopy, x)
					xcopy[run.idx] += run.pt.Loc * step
					run.result = f(xcopy)
					ansChan <- run
				}
			}
		}(sendChan, ansChan, quit)
	}

	// Launch the distributor. Distributor sends the cases to be computed.
	go func(sendChan chan<- fdrun, ansChan chan<- fdrun) {
		for i := range x {
			for _, pt := range formula.Stencil {
				if settings.OriginKnown && pt.Loc == 0 {
					// Answer already known. Send the answer on the answer channel.
					ansChan <- fdrun{
						idx:    i,
						pt:     pt,
						result: settings.OriginValue,
					}
					continue
				}
				// Answer not known, send the answer to be computed.
				sendChan <- fdrun{
					idx: i,
					pt:  pt,
				}
			}
		}
	}(sendChan, ansChan)

	for i := range dst {
		dst[i] = 0
	}
	// Read in all of the results.
	for i := 0; i < expect; i++ {
		run := <-ansChan
		dst[run.idx] += run.pt.Coeff * run.result
	}
	floats.Scale(1/step, dst)
	return dst
}

type fdrun struct {
	idx    int
	pt     Point
	result float64
}

// Forward represents a first-order forward difference.
var Forward = Formula{
	Stencil:    []Point{{Loc: 0, Coeff: -1}, {Loc: 1, Coeff: 1}},
	Derivative: 1,
	Step:       1e-6,
}

// Backward represents a first-order backward difference.
var Backward = Formula{
	Stencil:    []Point{{Loc: -1, Coeff: -1}, {Loc: 0, Coeff: 1}},
	Derivative: 1,
	Step:       1e-6,
}

// Central represents a first-order central difference.
var Central = Formula{
	Stencil:    []Point{{Loc: -1, Coeff: -0.5}, {Loc: 1, Coeff: 0.5}},
	Derivative: 1,
	Step:       1e-6,
}

// Central2nd represents a secord-order central difference.
var Central2nd = Formula{
	Stencil:    []Point{{Loc: -1, Coeff: 1}, {Loc: 0, Coeff: -2}, {Loc: 1, Coeff: 1}},
	Derivative: 2,
	Step:       1e-3,
}
<|endoftext|>


<commit_before>package state

import (
	"encoding/json"
)

type Result struct {
	Consistent bool      // The state is consistent with the operating system
	Metadata   *Metadata // The metadata of the state which returned this result
	Message    string    // A message returned by the state
}

func ResultsToJson(results []Result) ([]byte, error) {
	data, err := json.Marshal(results)
	if err != nil {
		return []byte(``), err
	}
	return data, nil
}

func ResultsFromJson(data []byte) ([]Result, error) {
	results := make([]Result, 0)
	err := json.Unmarshal(data, &results)
	if err != nil {
		return nil, err
	}
	return results, nil
}
<commit_msg>Add ResultMap to results module<commit_after>package state

import (
	"encoding/json"
)

type Result struct {
	Consistent bool      // The state is consistent with the operating system
	Metadata   *Metadata // The metadata of the state which returned this result
	Message    string    // A message returned by the state
}

func ResultsFromJson(data []byte) ([]Result, error) {
	results := make([]Result, 0)
	err := json.Unmarshal(data, &results)
	if err != nil {
		return results, err
	}
	return results, nil
}

func ResultsToJson(results []Result) ([]byte, error) {
	var data []byte
	data, err := json.Marshal(results)
	if err != nil {
		return data, err
	}
	return data, nil
}

type ResultMap struct {
	Results map[string][]Result
}

func (rm *ResultMap) Add(host string, result Result) {
	rm.Results[host] = append(rm.Results[host], result)
}

func (rm *ResultMap) ToJSON() ([]byte, error) {
	data, err := json.Marshal(rm.Results)
	if err != nil {
		return []byte(``), err
	}
	return data, nil
}
<|endoftext|>


<commit_before>// Copyright (C) 2010, Kyle Lemons <kyle@kylelemons.net>.  All rights reserved.

package log4go

import (
	"fmt"
	"os"
	"time"
)

// This log writer sends output to a file
type FileLogWriter struct {
	rec chan *LogRecord
	rot chan bool

	// The opened file
	filename string
	file     *os.File

	// The logging format
	format string

	// File header/trailer
	header, trailer string

	// Rotate at linecount
	maxlines          int
	maxlines_curlines int

	// Rotate at size
	maxsize         int
	maxsize_cursize int

	// Rotate daily
	daily          bool
	daily_opendate int

	// Keep old logfiles (.001, .002, etc)
	rotate bool
}

// This is the FileLogWriter's output method
func (w *FileLogWriter) LogWrite(rec *LogRecord) {
	w.rec <- rec
}

func (w *FileLogWriter) Close() {
	close(w.rec)
}

// NewFileLogWriter creates a new LogWriter which writes to the given file and
// has rotation enabled if rotate is true.
//
// If rotate is true, any time a new log file is opened, the old one is renamed
// with a .### extension to preserve it.  The various Set* methods can be used
// to configure log rotation based on lines, size, and daily.
//
// The standard log-line format is:
//   [%D %T] [%L] (%S) %M
func NewFileLogWriter(fname string, rotate bool) *FileLogWriter {
	w := &FileLogWriter{
		rec:      make(chan *LogRecord, LogBufferLength),
		rot:      make(chan bool),
		filename: fname,
		format:   "[%D %T] [%L] (%S) %M",
		rotate:   rotate,
	}

	// open the file for the first time
	if err := w.intRotate(); err != nil {
		fmt.Fprintf(os.Stderr, "FileLogWriter(%q): %s\n", w.filename, err)
		return nil
	}

	go func() {
		defer func() {
			if w.file != nil {
				fmt.Fprint(w.file, FormatLogRecord(w.trailer, &LogRecord{Created: time.Now()}))
				w.file.Close()
			}
		}()

		for {
			select {
			case <-w.rot:
				if err := w.intRotate(); err != nil {
					fmt.Fprintf(os.Stderr, "FileLogWriter(%q): %s\n", w.filename, err)
					return
				}
			case rec, ok := <-w.rec:
				if !ok {
					return
				}
				now := time.Now()
				if (w.maxlines > 0 && w.maxlines_curlines >= w.maxlines) ||
					(w.maxsize > 0 && w.maxsize_cursize >= w.maxsize) ||
					(w.daily && now.Day() != w.daily_opendate) {
					if err := w.intRotate(); err != nil {
						fmt.Fprintf(os.Stderr, "FileLogWriter(%q): %s\n", w.filename, err)
						return
					}
				}

				// Perform the write
				n, err := fmt.Fprint(w.file, FormatLogRecord(w.format, rec))
				if err != nil {
					fmt.Fprintf(os.Stderr, "FileLogWriter(%q): %s\n", w.filename, err)
					return
				}

				// Update the counts
				w.maxlines_curlines++
				w.maxsize_cursize += n
			}
		}
	}()

	return w
}

// Request that the logs rotate
func (w *FileLogWriter) Rotate() {
	w.rot <- true
}

// If this is called in a threaded context, it MUST be synchronized
func (w *FileLogWriter) intRotate() error {
	// Close any log file that may be open
	if w.file != nil {
		fmt.Fprint(w.file, FormatLogRecord(w.trailer, &LogRecord{Created: time.Now()}))
		w.file.Close()
	}

	// If we are keeping log files, move it to the next available number
	if w.rotate {
		_, err := os.Lstat(w.filename)
		if err == nil { // file exists
			// Find the next available number
			num := 1
			fname := ""
			for ; err == nil && num <= 999; num++ {
				fname = w.filename + fmt.Sprintf(".%03d", num)
				_, err = os.Lstat(fname)
			}
			// return error if the last file checked still existed
			if err == nil {
				return fmt.Errorf("Rotate: Cannot find free log number to rename %s\n", w.filename)
			}

			// Rename the file to its newfound home
			err = os.Rename(w.filename, fname)
			if err != nil {
				return fmt.Errorf("Rotate: %s\n", err)
			}
		}
	}

	// Open the log file
	fd, err := os.OpenFile(w.filename, os.O_WRONLY|os.O_APPEND|os.O_CREATE, 0660)
	if err != nil {
		return err
	}
	w.file = fd

	now := time.Now()
	fmt.Fprint(w.file, FormatLogRecord(w.header, &LogRecord{Created: now}))

	// Set the daily open date to the current date
	w.daily_opendate = now.Day()

	// initialize rotation values
	w.maxlines_curlines = 0
	w.maxsize_cursize = 0

	return nil
}

// Set the logging format (chainable).  Must be called before the first log
// message is written.
func (w *FileLogWriter) SetFormat(format string) *FileLogWriter {
	w.format = format
	return w
}

// Set the logfile header and footer (chainable).  Must be called before the first log
// message is written.  These are formatted similar to the FormatLogRecord (e.g.
// you can use %D and %T in your header/footer for date and time).
func (w *FileLogWriter) SetHeadFoot(head, foot string) *FileLogWriter {
	w.header, w.trailer = head, foot
	if w.maxlines_curlines == 0 {
		fmt.Fprint(w.file, FormatLogRecord(w.header, &LogRecord{Created: time.Now()}))
	}
	return w
}

// Set rotate at linecount (chainable). Must be called before the first log
// message is written.
func (w *FileLogWriter) SetRotateLines(maxlines int) *FileLogWriter {
	//fmt.Fprintf(os.Stderr, "FileLogWriter.SetRotateLines: %v\n", maxlines)
	w.maxlines = maxlines
	return w
}

// Set rotate at size (chainable). Must be called before the first log message
// is written.
func (w *FileLogWriter) SetRotateSize(maxsize int) *FileLogWriter {
	//fmt.Fprintf(os.Stderr, "FileLogWriter.SetRotateSize: %v\n", maxsize)
	w.maxsize = maxsize
	return w
}

// Set rotate daily (chainable). Must be called before the first log message is
// written.
func (w *FileLogWriter) SetRotateDaily(daily bool) *FileLogWriter {
	//fmt.Fprintf(os.Stderr, "FileLogWriter.SetRotateDaily: %v\n", daily)
	w.daily = daily
	return w
}

// SetRotate changes whether or not the old logs are kept. (chainable) Must be
// called before the first log message is written.  If rotate is false, the
// files are overwritten; otherwise, they are rotated to another file before the
// new log is opened.
func (w *FileLogWriter) SetRotate(rotate bool) *FileLogWriter {
	//fmt.Fprintf(os.Stderr, "FileLogWriter.SetRotate: %v\n", rotate)
	w.rotate = rotate
	return w
}

// NewXMLLogWriter is a utility method for creating a FileLogWriter set up to
// output XML record log messages instead of line-based ones.
func NewXMLLogWriter(fname string, rotate bool) *FileLogWriter {
	return NewFileLogWriter(fname, rotate).SetFormat(
		`	<record level="%L">
		<timestamp>%D %T</timestamp>
		<source>%S</source>
		<message>%M</message>
	</record>`).SetHeadFoot("<log created=\"%D %T\">", "</log>")
}
<commit_msg>logrotate功能改进<commit_after>// Copyright (C) 2010, Kyle Lemons <kyle@kylelemons.net>.  All rights reserved.

package log4go

import (
	"fmt"
	"io/ioutil"
	"os"
	"path/filepath"
	"sort"
	"strings"
	"time"
)

// This log writer sends output to a file
type FileLogWriter struct {
	rec chan *LogRecord
	rot chan bool

	// The opened file
	filename string
	file     *os.File

	// The logging format
	format string

	// File header/trailer
	header, trailer string

	// Rotate at linecount
	maxlines          int
	maxlines_curlines int

	// Rotate at size
	maxsize         int
	maxsize_cursize int

	// Rotate daily
	daily          bool
	daily_opendate int

	// Keep old logfiles (.001, .002, etc)
	rotate   bool
	keep_old int
}

// This is the FileLogWriter's output method
func (w *FileLogWriter) LogWrite(rec *LogRecord) {
	w.rec <- rec
}

func (w *FileLogWriter) Close() {
	close(w.rec)
}

// NewFileLogWriter creates a new LogWriter which writes to the given file and
// has rotation enabled if rotate is true.
//
// If rotate is true, any time a new log file is opened, the old one is renamed
// with a .### extension to preserve it.  The various Set* methods can be used
// to configure log rotation based on lines, size, and daily.
//
// The standard log-line format is:
//   [%D %T] [%L] (%S) %M
func NewFileLogWriter(fname string, rotate bool) *FileLogWriter {
	w := &FileLogWriter{
		rec:      make(chan *LogRecord, LogBufferLength),
		rot:      make(chan bool),
		filename: fname,
		format:   "[%D %T] [%L] (%S) %M",
		rotate:   rotate,
	}

	// open the file for the first time
	if err := w.intRotate(); err != nil {
		fmt.Fprintf(os.Stderr, "FileLogWriter(%q): %s\n", w.filename, err)
		return nil
	}

	go func() {
		defer func() {
			if w.file != nil {
				fmt.Fprint(w.file, FormatLogRecord(w.trailer, &LogRecord{Created: time.Now()}))
				w.file.Close()
			}
		}()

		for {
			select {
			case <-w.rot:
				if err := w.intRotate(); err != nil {
					fmt.Fprintf(os.Stderr, "FileLogWriter(%q): %s\n", w.filename, err)
					return
				}
			case rec, ok := <-w.rec:
				if !ok {
					return
				}
				now := time.Now()
				if (w.maxlines > 0 && w.maxlines_curlines >= w.maxlines) ||
					(w.maxsize > 0 && w.maxsize_cursize >= w.maxsize) ||
					(w.daily && now.Day() != w.daily_opendate) {
					if err := w.intRotate(); err != nil {
						fmt.Fprintf(os.Stderr, "FileLogWriter(%q): %s\n", w.filename, err)
						return
					}
				}

				// Perform the write
				n, err := fmt.Fprint(w.file, FormatLogRecord(w.format, rec))
				if err != nil {
					fmt.Fprintf(os.Stderr, "FileLogWriter(%q): %s\n", w.filename, err)
					return
				}

				// Update the counts
				w.maxlines_curlines++
				w.maxsize_cursize += n
			}
		}
	}()

	return w
}

// Request that the logs rotate
func (w *FileLogWriter) Rotate() {
	w.rot <- true
}

// If this is called in a threaded context, it MUST be synchronized
func (w *FileLogWriter) intRotate() error {
	// Close any log file that may be open
	if w.file != nil {
		fmt.Fprint(w.file, FormatLogRecord(w.trailer, &LogRecord{Created: time.Now()}))
		w.file.Close()
	}

	// If we are keeping log files, move it to the next available number
	if w.rotate {
		_, err := os.Lstat(w.filename)
		if err == nil { // file exists
			// Find the next available number
			// num := 1
			// fname := ""
			// for ; err == nil && num <= 999; num++ {
			// 	fname = w.filename + fmt.Sprintf(".%03d", num)
			// 	_, err = os.Lstat(fname)
			// }
			// // return error if the last file checked still existed
			// if err == nil {
			// 	return fmt.Errorf("Rotate: Cannot find free log number to rename %s\n", w.filename)
			// }

			fname := w.filename + time.Now().Format(".20060102-15:04:05.oldlog")

			// Rename the file to its newfound home
			err = os.Rename(w.filename, fname)
			if err != nil {
				return fmt.Errorf("Rotate: %s\n", err)
			}
		}

		// TODO 通过w.filename拿到所在目录，去那里查找
		if w.keep_old > 0 {
			log_dir := filepath.Dir(w.filename)

			oldlogs, err := ListLogs(log_dir, ".oldlog")
			if err == nil {
				overed := len(oldlogs) - w.keep_old
				if overed > 0 {
					for _, _log := range oldlogs[0:overed] {
						remove_old_log(_log)
					}
				}
			}
		}
	}

	// Open the log file
	fd, err := os.OpenFile(w.filename, os.O_WRONLY|os.O_APPEND|os.O_CREATE, 0660)
	if err != nil {
		return err
	}
	w.file = fd

	now := time.Now()
	fmt.Fprint(w.file, FormatLogRecord(w.header, &LogRecord{Created: now}))

	// Set the daily open date to the current date
	w.daily_opendate = now.Day()

	// initialize rotation values
	w.maxlines_curlines = 0
	w.maxsize_cursize = 0

	return nil
}

// Set the logging format (chainable).  Must be called before the first log
// message is written.
func (w *FileLogWriter) SetFormat(format string) *FileLogWriter {
	w.format = format
	return w
}

// Set the logfile header and footer (chainable).  Must be called before the first log
// message is written.  These are formatted similar to the FormatLogRecord (e.g.
// you can use %D and %T in your header/footer for date and time).
func (w *FileLogWriter) SetHeadFoot(head, foot string) *FileLogWriter {
	w.header, w.trailer = head, foot
	if w.maxlines_curlines == 0 {
		fmt.Fprint(w.file, FormatLogRecord(w.header, &LogRecord{Created: time.Now()}))
	}
	return w
}

// Set rotate at linecount (chainable). Must be called before the first log
// message is written.
func (w *FileLogWriter) SetRotateLines(maxlines int) *FileLogWriter {
	//fmt.Fprintf(os.Stderr, "FileLogWriter.SetRotateLines: %v\n", maxlines)
	w.maxlines = maxlines
	return w
}

// Set rotate at size (chainable). Must be called before the first log message
// is written.
func (w *FileLogWriter) SetRotateSize(maxsize int) *FileLogWriter {
	//fmt.Fprintf(os.Stderr, "FileLogWriter.SetRotateSize: %v\n", maxsize)
	w.maxsize = maxsize
	return w
}

// Set rotate daily (chainable). Must be called before the first log message is
// written.
func (w *FileLogWriter) SetRotateDaily(daily bool) *FileLogWriter {
	//fmt.Fprintf(os.Stderr, "FileLogWriter.SetRotateDaily: %v\n", daily)
	w.daily = daily
	return w
}

// SetRotate changes whether or not the old logs are kept. (chainable) Must be
// called before the first log message is written.  If rotate is false, the
// files are overwritten; otherwise, they are rotated to another file before the
// new log is opened.
func (w *FileLogWriter) SetRotate(rotate bool) *FileLogWriter {
	//fmt.Fprintf(os.Stderr, "FileLogWriter.SetRotate: %v\n", rotate)
	w.rotate = rotate
	return w
}

func (w *FileLogWriter) SetRotateKeep(keep int) *FileLogWriter {
	w.keep_old = keep

	return w
}

// NewXMLLogWriter is a utility method for creating a FileLogWriter set up to
// output XML record log messages instead of line-based ones.
func NewXMLLogWriter(fname string, rotate bool) *FileLogWriter {
	return NewFileLogWriter(fname, rotate).SetFormat(
		`	<record level="%L">
		<timestamp>%D %T</timestamp>
		<source>%S</source>
		<message>%M</message>
	</record>`).SetHeadFoot("<log created=\"%D %T\">", "</log>")
}

func ListLogs(dirPth string, suffix string) (files []string, err error) {
	dir, err := ioutil.ReadDir(dirPth)
	if err != nil {
		return nil, err
	}

	sort.Slice(dir, func(i, j int) bool {
		if dir[i].ModTime().Before(dir[j].ModTime()) {
			return true
		} else {
			return false
		}
	})

	files = make([]string, 0, len(dir))

	for _, fi := range dir {
		if fi.IsDir() || !strings.HasSuffix(fi.Name(), suffix) {
			continue
		}

		files = append(files, fi.Name())
	}

	return
}

func remove_old_log(log string) {
	os.Remove(log)
}
<|endoftext|>


<commit_before>package pg

import (
	"errors"
	"sync"
	"time"

	"github.com/go-pg/pg/internal"
	"github.com/go-pg/pg/internal/pool"
	"github.com/go-pg/pg/types"
)

const gopgChannel = "gopg:ping"

var errListenerClosed = errors.New("pg: listener is closed")
var errPingTimeout = errors.New("pg: ping timeout")

// A notification received with LISTEN command.
type Notification struct {
	Channel string
	Payload string
}

// Listener listens for notifications sent with NOTIFY command.
// It's NOT safe for concurrent use by multiple goroutines
// except the Channel API.
type Listener struct {
	db *DB

	channels []string

	mu     sync.Mutex
	cn     *pool.Conn
	closed bool
	exit   chan struct{}

	chOnce sync.Once
	ch     chan *Notification
	pingCh chan struct{}
}

func (ln *Listener) init() {
	ln.exit = make(chan struct{})
}

func (ln *Listener) conn(readTimeout time.Duration) (*pool.Conn, error) {
	ln.mu.Lock()
	cn, err := ln._conn()
	ln.mu.Unlock()

	switch err {
	case nil:
		cn.SetTimeout(readTimeout, ln.db.opt.WriteTimeout)
		return cn, nil
	case errListenerClosed:
		return nil, err
	case pool.ErrClosed:
		_ = ln.Close()
		return nil, errListenerClosed
	default:
		internal.Logf("pg: Listen failed: %s", err)
		return nil, err
	}
}

func (ln *Listener) _conn() (*pool.Conn, error) {
	if ln.closed {
		return nil, errListenerClosed
	}

	if ln.cn != nil {
		return ln.cn, nil
	}

	cn, err := ln.db.pool.NewConn()
	if err != nil {
		return nil, err
	}
	cn.EnableConcurrentWrites()

	if cn.InitedAt.IsZero() {
		err := ln.db.initConn(cn)
		if err != nil {
			_ = ln.db.pool.CloseConn(cn)
			return nil, err
		}
		cn.InitedAt = time.Now()
	}

	if len(ln.channels) > 0 {
		err := ln.listen(cn, ln.channels...)
		if err != nil {
			_ = ln.db.pool.CloseConn(cn)
			return nil, err
		}
	}

	ln.cn = cn
	return cn, nil
}

func (ln *Listener) releaseConn(cn *pool.Conn, err error, allowTimeout bool) {
	ln.mu.Lock()
	if ln.cn == cn {
		if isBadConn(err, allowTimeout) {
			ln._reconnect(errPingTimeout)
		}
	}
	ln.mu.Unlock()
}

func (ln *Listener) _closeTheCn(reason error) error {
	if ln.cn == nil {
		return nil
	}
	if !ln.closed {
		internal.Logf("pg: discarding bad listener connection: %s", reason)
	}

	err := ln.db.pool.CloseConn(ln.cn)
	ln.cn = nil
	return err
}

func (ln *Listener) _reconnect(reason error) {
	_ = ln._closeTheCn(reason)
	_, _ = ln._conn()
}

// Close closes the listener, releasing any open resources.
func (ln *Listener) Close() error {
	ln.mu.Lock()
	defer ln.mu.Unlock()

	if ln.closed {
		return errListenerClosed
	}
	ln.closed = true
	close(ln.exit)

	return ln._closeTheCn(errListenerClosed)
}

// Listen starts listening for notifications on channels.
func (ln *Listener) Listen(channels ...string) error {
	cn, err := ln.conn(ln.db.opt.ReadTimeout)
	if err != nil {
		return err
	}

	err = ln.listen(cn, channels...)
	if err != nil {
		ln.releaseConn(cn, err, false)
		return err
	}

	ln.channels = appendIfNotExists(ln.channels, channels...)
	return nil
}

func (ln *Listener) listen(cn *pool.Conn, channels ...string) error {
	buf := cn.PrepareWriteBuffer()
	for _, channel := range channels {
		err := writeQueryMsg(buf, ln.db, "LISTEN ?", pgChan(channel))
		if err != nil {
			return err
		}
	}
	return cn.FlushWriteBuffer(buf)
}

// Receive indefinitely waits for a notification. This is low-level API
// and in most cases Channel should be used instead.
func (ln *Listener) Receive() (channel string, payload string, err error) {
	return ln.ReceiveTimeout(0)
}

// ReceiveTimeout waits for a notification until timeout is reached.
// This is low-level API and in most cases Channel should be used instead.
func (ln *Listener) ReceiveTimeout(timeout time.Duration) (channel, payload string, err error) {
	cn, err := ln.conn(timeout)
	if err != nil {
		return "", "", err
	}

	channel, payload, err = readNotification(cn)
	if err != nil {
		ln.releaseConn(cn, err, timeout > 0)
		return "", "", err
	}

	return channel, payload, nil
}

// Channel returns a channel for concurrently receiving notifications.
// It periodically sends Ping messages to test connection health.
//
// The channel is closed with Listener. Receive* APIs can not be used
// after channel is created.
func (ln *Listener) Channel() <-chan *Notification {
	ln.chOnce.Do(ln.initChannel)
	return ln.ch
}

func (ln *Listener) initChannel() {
	_ = ln.Listen(gopgChannel)

	ln.ch = make(chan *Notification, 100)
	ln.pingCh = make(chan struct{}, 10)

	go func() {
		var errCount int
		for {
			channel, payload, err := ln.Receive()
			if err != nil {
				if err == errListenerClosed {
					close(ln.ch)
					return
				}
				if errCount > 0 {
					time.Sleep(ln.db.retryBackoff(errCount))
				}
				errCount++
				continue
			}
			errCount = 0

			// Any message is as good as a ping.
			select {
			case ln.pingCh <- struct{}{}:
			default:
			}

			switch channel {
			case gopgChannel:
				// ignore
			default:
				ln.ch <- &Notification{channel, payload}
			}
		}
	}()

	go func() {
		const timeout = 5 * time.Second

		timer := time.NewTimer(timeout)
		timer.Stop()

		var hasPing bool
		for {
			timer.Reset(timeout)
			select {
			case <-ln.pingCh:
				hasPing = true
				if !timer.Stop() {
					<-timer.C
				}
			case <-timer.C:
				if hasPing {
					hasPing = false
					_ = ln.ping()
				} else {
					ln.mu.Lock()
					ln._reconnect(errPingTimeout)
					ln.mu.Unlock()
				}
			case <-ln.exit:
				return
			}
		}
	}()
}

func (ln *Listener) ping() error {
	_, err := ln.db.Exec("NOTIFY ?", pgChan(gopgChannel))
	return err
}

func appendIfNotExists(ss []string, es ...string) []string {
loop:
	for _, e := range es {
		for _, s := range ss {
			if s == e {
				continue loop
			}
		}
		ss = append(ss, e)
	}
	return ss
}

type pgChan string

var _ types.ValueAppender = pgChan("")

func (ch pgChan) AppendValue(b []byte, quote int) []byte {
	if quote == 0 {
		return append(b, ch...)
	}

	b = append(b, '"')
	for _, c := range []byte(ch) {
		if c == '"' {
			b = append(b, '"', '"')
		} else {
			b = append(b, c)
		}
	}
	b = append(b, '"')

	return b
}
<commit_msg>Fix Listener log message<commit_after>package pg

import (
	"errors"
	"sync"
	"time"

	"github.com/go-pg/pg/internal"
	"github.com/go-pg/pg/internal/pool"
	"github.com/go-pg/pg/types"
)

const gopgChannel = "gopg:ping"

var errListenerClosed = errors.New("pg: listener is closed")
var errPingTimeout = errors.New("pg: ping timeout")

// A notification received with LISTEN command.
type Notification struct {
	Channel string
	Payload string
}

// Listener listens for notifications sent with NOTIFY command.
// It's NOT safe for concurrent use by multiple goroutines
// except the Channel API.
type Listener struct {
	db *DB

	channels []string

	mu     sync.Mutex
	cn     *pool.Conn
	closed bool
	exit   chan struct{}

	chOnce sync.Once
	ch     chan *Notification
	pingCh chan struct{}
}

func (ln *Listener) init() {
	ln.exit = make(chan struct{})
}

func (ln *Listener) conn(readTimeout time.Duration) (*pool.Conn, error) {
	ln.mu.Lock()
	cn, err := ln._conn()
	ln.mu.Unlock()

	switch err {
	case nil:
		cn.SetTimeout(readTimeout, ln.db.opt.WriteTimeout)
		return cn, nil
	case errListenerClosed:
		return nil, err
	case pool.ErrClosed:
		_ = ln.Close()
		return nil, errListenerClosed
	default:
		internal.Logf("pg: Listen failed: %s", err)
		return nil, err
	}
}

func (ln *Listener) _conn() (*pool.Conn, error) {
	if ln.closed {
		return nil, errListenerClosed
	}

	if ln.cn != nil {
		return ln.cn, nil
	}

	cn, err := ln.db.pool.NewConn()
	if err != nil {
		return nil, err
	}
	cn.EnableConcurrentWrites()

	if cn.InitedAt.IsZero() {
		err := ln.db.initConn(cn)
		if err != nil {
			_ = ln.db.pool.CloseConn(cn)
			return nil, err
		}
		cn.InitedAt = time.Now()
	}

	if len(ln.channels) > 0 {
		err := ln.listen(cn, ln.channels...)
		if err != nil {
			_ = ln.db.pool.CloseConn(cn)
			return nil, err
		}
	}

	ln.cn = cn
	return cn, nil
}

func (ln *Listener) releaseConn(cn *pool.Conn, err error, allowTimeout bool) {
	ln.mu.Lock()
	if ln.cn == cn {
		if isBadConn(err, allowTimeout) {
			ln._reconnect(err)
		}
	}
	ln.mu.Unlock()
}

func (ln *Listener) _closeTheCn(reason error) error {
	if ln.cn == nil {
		return nil
	}
	if !ln.closed {
		internal.Logf("pg: discarding bad listener connection: %s", reason)
	}

	err := ln.db.pool.CloseConn(ln.cn)
	ln.cn = nil
	return err
}

func (ln *Listener) _reconnect(reason error) {
	_ = ln._closeTheCn(reason)
	_, _ = ln._conn()
}

// Close closes the listener, releasing any open resources.
func (ln *Listener) Close() error {
	ln.mu.Lock()
	defer ln.mu.Unlock()

	if ln.closed {
		return errListenerClosed
	}
	ln.closed = true
	close(ln.exit)

	return ln._closeTheCn(errListenerClosed)
}

// Listen starts listening for notifications on channels.
func (ln *Listener) Listen(channels ...string) error {
	cn, err := ln.conn(ln.db.opt.ReadTimeout)
	if err != nil {
		return err
	}

	err = ln.listen(cn, channels...)
	if err != nil {
		ln.releaseConn(cn, err, false)
		return err
	}

	ln.channels = appendIfNotExists(ln.channels, channels...)
	return nil
}

func (ln *Listener) listen(cn *pool.Conn, channels ...string) error {
	buf := cn.PrepareWriteBuffer()
	for _, channel := range channels {
		err := writeQueryMsg(buf, ln.db, "LISTEN ?", pgChan(channel))
		if err != nil {
			return err
		}
	}
	return cn.FlushWriteBuffer(buf)
}

// Receive indefinitely waits for a notification. This is low-level API
// and in most cases Channel should be used instead.
func (ln *Listener) Receive() (channel string, payload string, err error) {
	return ln.ReceiveTimeout(0)
}

// ReceiveTimeout waits for a notification until timeout is reached.
// This is low-level API and in most cases Channel should be used instead.
func (ln *Listener) ReceiveTimeout(timeout time.Duration) (channel, payload string, err error) {
	cn, err := ln.conn(timeout)
	if err != nil {
		return "", "", err
	}

	channel, payload, err = readNotification(cn)
	if err != nil {
		ln.releaseConn(cn, err, timeout > 0)
		return "", "", err
	}

	return channel, payload, nil
}

// Channel returns a channel for concurrently receiving notifications.
// It periodically sends Ping messages to test connection health.
//
// The channel is closed with Listener. Receive* APIs can not be used
// after channel is created.
func (ln *Listener) Channel() <-chan *Notification {
	ln.chOnce.Do(ln.initChannel)
	return ln.ch
}

func (ln *Listener) initChannel() {
	_ = ln.Listen(gopgChannel)

	ln.ch = make(chan *Notification, 100)
	ln.pingCh = make(chan struct{}, 10)

	go func() {
		var errCount int
		for {
			channel, payload, err := ln.Receive()
			if err != nil {
				if err == errListenerClosed {
					close(ln.ch)
					return
				}
				if errCount > 0 {
					time.Sleep(ln.db.retryBackoff(errCount))
				}
				errCount++
				continue
			}
			errCount = 0

			// Any message is as good as a ping.
			select {
			case ln.pingCh <- struct{}{}:
			default:
			}

			switch channel {
			case gopgChannel:
				// ignore
			default:
				ln.ch <- &Notification{channel, payload}
			}
		}
	}()

	go func() {
		const timeout = 5 * time.Second

		timer := time.NewTimer(timeout)
		timer.Stop()

		var hasPing bool
		for {
			timer.Reset(timeout)
			select {
			case <-ln.pingCh:
				hasPing = true
				if !timer.Stop() {
					<-timer.C
				}
			case <-timer.C:
				if hasPing {
					hasPing = false
					err := ln.ping()
					if err != nil {
						internal.Logf("pg.Listener: ping failed: %s", err)
					}
				} else {
					ln.mu.Lock()
					ln._reconnect(errPingTimeout)
					ln.mu.Unlock()
				}
			case <-ln.exit:
				return
			}
		}
	}()
}

func (ln *Listener) ping() error {
	_, err := ln.db.Exec("NOTIFY ?", pgChan(gopgChannel))
	return err
}

func appendIfNotExists(ss []string, es ...string) []string {
loop:
	for _, e := range es {
		for _, s := range ss {
			if s == e {
				continue loop
			}
		}
		ss = append(ss, e)
	}
	return ss
}

type pgChan string

var _ types.ValueAppender = pgChan("")

func (ch pgChan) AppendValue(b []byte, quote int) []byte {
	if quote == 0 {
		return append(b, ch...)
	}

	b = append(b, '"')
	for _, c := range []byte(ch) {
		if c == '"' {
			b = append(b, '"', '"')
		} else {
			b = append(b, c)
		}
	}
	b = append(b, '"')

	return b
}
<|endoftext|>


<commit_before>package app

import "log"

type logger struct {
}

// Log satisfies the app.Logger interface.
func (l *logger) Log(v ...interface{}) {
	log.Println(v...)
}

// Logf satisfies the app.Logger interface.
func (l *logger) Logf(format string, v ...interface{}) {
	log.Printf(format, v...)
}

// Error satisfies the app.Logger interface.
func (l *logger) Error(v ...interface{}) {
	log.Println(v...)
}

// Errorf satisfies the app.Logger interface.
func (l *logger) Errorf(format string, v ...interface{}) {
	log.Printf(format, v...)
}
<commit_msg>cleanup<commit_after>package app

import "log"

type logger struct {
}

func (l *logger) Log(v ...interface{}) {
	log.Println(v...)
}

func (l *logger) Logf(format string, v ...interface{}) {
	log.Printf(format, v...)
}

func (l *logger) Error(v ...interface{}) {
	log.Println(v...)
}

func (l *logger) Errorf(format string, v ...interface{}) {
	log.Printf(format, v...)
}
<|endoftext|>


<commit_before>package pubsub

import (
	check "gopkg.in/check.v1"
	"testing"
	"log"
)

var _ = check.Suite(new(Suite))

func Test(t *testing.T) {
	check.TestingT(t)
}

type Suite struct{}

func (s *Suite) TestSub(ch *check.C) {
	pubsub := NewPubsub()
	var val string

	pubsub.On("hello", func(data []interface{}) {
		val = data[0].(string)
	})
	pubsub.Publish("hello", "world")

	ch.Check(val, check.Equals, "world")
	pubsub.Publish("hello", "globe")

	ch.Check(val, check.Equals, "globe")

	pubsub.Publish("hello", "one")
	pubsub.Publish("hello", "two")

	ch.Check(val, check.Equals, "two")
}

func (s *Suite) TestMoreSubs(ch *check.C) {
	pubsub := NewPubsub()
	val1 := 0
	val2 := "test"
	val3 := []int{}

	pubsub.On("hello", func(data []interface{}) {
		val, ok := data[0].(int)
		if(ok) {
			val1 = val
		}
	})
	pubsub.On("hello", func(data []interface{}) {
		val, ok := data[0].(string)
		if(ok) {
			val2 = val
		}
	})
	pubsub.On("hello", func(data []interface{}) {
		val, ok := data[0].(int)
		if(ok) {
			val3 = append(val3, val)
		}
	})
	ch.Check(val1, check.Equals, 0)
	ch.Check(val2, check.Equals, "test")
	ch.Check(len(val3), check.Equals, 0)

	pubsub.Publish("hello", "world")

	ch.Check(val1, check.Equals, 0)
	ch.Check(val2, check.Equals, "world")
	ch.Check(len(val3), check.Equals, 0)

	pubsub.Publish("hello", 5)
	ch.Check(val1, check.Equals, 5)
	ch.Check(val2, check.Equals, "world")
	ch.Check(len(val3), check.Equals, 1)
	ch.Check(val3[0], check.Equals, 5)
}

func (s *Suite) TestChaining(ch *check.C) {
	pubsub := NewPubsub()
	val1 := "test"

	pubsub.On("hello", func(data []interface{}) {
		val, ok := data[0].(string)
		if(ok) {
			val1 = val
		}
	})

	pubsub.Publish("hello", "world").Publish("hello", "globe")

	ch.Check(val1, check.Equals, "globe")
}

func (s *Suite) TestConcurrentCallback(ch *check.C) {
	pubsub := NewPubsub()
	var counter int
	ch1 := make(chan int)

	pubsub.On("hello", func(data []interface{}) {
		go func() {
			counter += data[0].(int)
			ch1 <- counter
		}()
	})

	pubsub.Publish("hello", 1)

	ch.Check(<-ch1, check.Equals, 1)
	ch.Check(counter, check.Equals, 1)

	pubsub.Publish("hello", 2)
	ch.Check(<-ch1, check.Equals, 3)
	ch.Check(counter, check.Equals, 3)
}

func (s *Suite) TestUnsubscribe(ch *check.C) {
	pubsub := NewPubsub()
	var counter int

	sub := pubsub.On("hello", func(data []interface{}) {
		counter += data[0].(int)
	})

	pubsub.Publish("hello", 3)

	ch.Check(counter, check.Equals, 3)

	pubsub.Publish("hello", 5)
	ch.Check(counter, check.Equals, 8)

	sub.Off()
	pubsub.Publish("hello", 5)
	ch.Check(counter, check.Equals, 8)
	pubsub.Publish("hello", 5)
	ch.Check(counter, check.Equals, 8)
}

func (s *Suite) TestPubsubNewGoroutine(ch *check.C) {
	pubsub := NewPubsub(true)
	counter := 0
	ch1 := make(chan int)

	sub := pubsub.On("hello", func(data []interface{}) {
		counter += data[0].(int)
		ch1 <- counter
	})

	pubsub.Publish("hello", 3)

	ch.Check(counter, check.Equals, 0)
	<-ch1
	ch.Check(counter, check.Equals, 3)

	pubsub.Publish("hello", 5)
	ch.Check(counter, check.Equals, 3)
	<-ch1
	ch.Check(counter, check.Equals, 8)

	sub.Off()
	pubsub.Publish("hello", 5)
	ch.Check(counter, check.Equals, 8)
	pubsub.Publish("hello", 5)
	ch.Check(counter, check.Equals, 8)
}

func (s *Suite) TestPublishToUnsubscribed(ch *check.C) {
	pubsub := NewPubsub(true)
	counter := 0
	ch1 := make(chan int)

	sub := pubsub.On("hello", func(data []interface{}) {
		counter += data[0].(int)
		ch1 <- counter
	})

	pubsub.Publish("hello", 3)

	ch.Check(counter, check.Equals, 0)
	<-ch1
	ch.Check(counter, check.Equals, 3)

	pubsub.Publish("hello", 5)
	ch.Check(counter, check.Equals, 3)
	<-ch1
	ch.Check(counter, check.Equals, 8)

	sub.Off()
	pubsub.Publish("hello", 5)
	ch.Check(counter, check.Equals, 8)
	pubsub.Publish("world", 5)
	ch.Check(counter, check.Equals, 8)
}

func (s *Suite) TestPublishMultipleArgs(ch *check.C) {
	pubsub := NewPubsub()
	counter := 0

	pubsub.On("hello", func(data []interface{}) {
		log.Println(data)

		for _, num := range data {
			log.Println(num)
			counter += num.(int)
		}
	})

	pubsub.Publish("hello", 3)
	ch.Check(counter, check.Equals, 3)

	pubsub.Publish("hello", 1, 2)
	ch.Check(counter, check.Equals, 6)
}<commit_msg>Fix race condition in tests<commit_after>package pubsub

import (
	check "gopkg.in/check.v1"
	"testing"
	"log"
	"sync/atomic"
	"sync"
)

var _ = check.Suite(new(Suite))

func Test(t *testing.T) {
	check.TestingT(t)
}

type Suite struct{}

func (s *Suite) TestSub(ch *check.C) {
	pubsub := NewPubsub()
	var val string

	pubsub.On("hello", func(data []interface{}) {
		val = data[0].(string)
	})
	pubsub.Publish("hello", "world")

	ch.Check(val, check.Equals, "world")
	pubsub.Publish("hello", "globe")

	ch.Check(val, check.Equals, "globe")

	pubsub.Publish("hello", "one")
	pubsub.Publish("hello", "two")

	ch.Check(val, check.Equals, "two")
}

func (s *Suite) TestMoreSubs(ch *check.C) {
	pubsub := NewPubsub()
	val1 := 0
	val2 := "test"
	val3 := []int{}

	pubsub.On("hello", func(data []interface{}) {
		val, ok := data[0].(int)
		if(ok) {
			val1 = val
		}
	})
	pubsub.On("hello", func(data []interface{}) {
		val, ok := data[0].(string)
		if(ok) {
			val2 = val
		}
	})
	pubsub.On("hello", func(data []interface{}) {
		val, ok := data[0].(int)
		if(ok) {
			val3 = append(val3, val)
		}
	})
	ch.Check(val1, check.Equals, 0)
	ch.Check(val2, check.Equals, "test")
	ch.Check(len(val3), check.Equals, 0)

	pubsub.Publish("hello", "world")

	ch.Check(val1, check.Equals, 0)
	ch.Check(val2, check.Equals, "world")
	ch.Check(len(val3), check.Equals, 0)

	pubsub.Publish("hello", 5)
	ch.Check(val1, check.Equals, 5)
	ch.Check(val2, check.Equals, "world")
	ch.Check(len(val3), check.Equals, 1)
	ch.Check(val3[0], check.Equals, 5)
}

func (s *Suite) TestChaining(ch *check.C) {
	pubsub := NewPubsub()
	val1 := "test"

	pubsub.On("hello", func(data []interface{}) {
		val, ok := data[0].(string)
		if(ok) {
			val1 = val
		}
	})

	pubsub.Publish("hello", "world").Publish("hello", "globe")

	ch.Check(val1, check.Equals, "globe")
}

func (s *Suite) TestConcurrentCallback(ch *check.C) {
	pubsub := NewPubsub()
	var counter int
	ch1 := make(chan int)

	pubsub.On("hello", func(data []interface{}) {
		go func() {
			counter += data[0].(int)
			ch1 <- counter
		}()
	})

	pubsub.Publish("hello", 1)

	ch.Check(<-ch1, check.Equals, 1)
	ch.Check(counter, check.Equals, 1)

	pubsub.Publish("hello", 2)
	ch.Check(<-ch1, check.Equals, 3)
	ch.Check(counter, check.Equals, 3)
}

func (s *Suite) TestMultipleConcurrentCallbacks(ch *check.C) {
	pubsub := NewPubsub(true)
	var counter uint64
	var wg sync.WaitGroup

	// ch1 := make(chan uint64)
    for i := 1; i <= 100; i++ {
		pubsub.On("hello", func(data []interface{}) {
			defer wg.Done()

			val, ok := data[0].(int)

			if (ok) {
				atomic.AddUint64(&counter, uint64(val))
			}
		})
    }

    for i := 1; i <= 2; i++ {
	    wg.Add(100)
		go pubsub.Publish("hello", i)
    }

	wg.Wait()

	ch.Check(counter, check.Equals, uint64(100 + 200))

	counter = uint64(0)

    for i := 1; i <= 5; i++ {
	    wg.Add(100)
		go pubsub.Publish("hello", i)
    }

	wg.Wait()

	ch.Check(counter, check.Equals, uint64(100 + 200 + 300 + 400 + 500))
}

func (s *Suite) TestUnsubscribe(ch *check.C) {
	pubsub := NewPubsub()
	var counter int

	sub := pubsub.On("hello", func(data []interface{}) {
		counter += data[0].(int)
	})

	pubsub.Publish("hello", 3)

	ch.Check(counter, check.Equals, 3)

	pubsub.Publish("hello", 5)
	ch.Check(counter, check.Equals, 8)

	sub.Off()
	pubsub.Publish("hello", 5)
	ch.Check(counter, check.Equals, 8)
	pubsub.Publish("hello", 5)
	ch.Check(counter, check.Equals, 8)
}

func (s *Suite) TestPubsubNewGoroutine(ch *check.C) {
	pubsub := NewPubsub(true)
	var counter uint64
	ch1 := make(chan uint64)

	sub := pubsub.On("hello", func(data []interface{}) {
		val, ok := data[0].(int)

		if (ok) {
			atomic.AddUint64(&counter, uint64(val))
		}

		ch1 <- counter
	})

	ch.Check(counter, check.Equals, uint64(0))
	pubsub.Publish("hello", 3)

	<-ch1
	ch.Check(counter, check.Equals, uint64(3))

	ch.Check(counter, check.Equals, uint64(3))
	pubsub.Publish("hello", 5)
	<-ch1
	ch.Check(counter, check.Equals, uint64(8))

	sub.Off()
	pubsub.Publish("hello", 5)
	ch.Check(counter, check.Equals, uint64(8))
	pubsub.Publish("hello", 5)
	ch.Check(counter, check.Equals, uint64(8))
}

func (s *Suite) TestPublishToUnsubscribed(ch *check.C) {
	pubsub := NewPubsub(true)
	counter := uint64(0)
	ch1 := make(chan uint64)

	sub := pubsub.On("hello", func(data []interface{}) {
		val, ok := data[0].(int)

		if (ok) {
			atomic.AddUint64(&counter, uint64(val))
		}

		ch1 <- counter
	})

	ch.Check(counter, check.Equals, uint64(0))
	pubsub.Publish("hello", 3)
	<-ch1
	ch.Check(counter, check.Equals, uint64(3))

	pubsub.Publish("hello", 5)
	<-ch1
	ch.Check(counter, check.Equals, uint64(8))

	sub.Off()

	pubsub.Publish("hello", 5)
	ch.Check(counter, check.Equals, uint64(8))
	pubsub.Publish("world", 5)
	ch.Check(counter, check.Equals, uint64(8))
}

func (s *Suite) TestPublishMultipleArgs(ch *check.C) {
	pubsub := NewPubsub()
	counter := 0

	pubsub.On("hello", func(data []interface{}) {
		log.Println(data)

		for _, num := range data {
			log.Println(num)
			counter += num.(int)
		}
	})

	pubsub.Publish("hello", 3)
	ch.Check(counter, check.Equals, 3)

	pubsub.Publish("hello", 1, 2)
	ch.Check(counter, check.Equals, 6)
}<|endoftext|>


<commit_before>package logstash

import (
	"encoding/json"
	"errors"
	"log"
	"net"

	"github.com/gliderlabs/logspout/router"
)

func init() {
	router.AdapterFactories.Register(NewLogstashAdapter, "logstash")
}

// LogstashAdapter is an adapter that streams UDP JSON to Logstash.
type LogstashAdapter struct {
	conn  net.Conn
	route *router.Route
}

// NewLogstashAdapter creates a LogstashAdapter with UDP as the default transport.
func NewLogstashAdapter(route *router.Route) (router.LogAdapter, error) {
	transport, found := router.AdapterTransports.Lookup(route.AdapterTransport("udp"))
	if !found {
		return nil, errors.New("unable to find adapter: " + route.Adapter)
	}

	conn, err := transport.Dial(route.Address, route.Options)
	if err != nil {
		return nil, err
	}

	return &LogstashAdapter{
		route: route,
		conn:  conn,
	}, nil
}

// Stream implements the router.LogAdapter interface.
func (a *LogstashAdapter) Stream(logstream chan *router.Message) {
	for m := range logstream {
		msg := LogstashMessage{
			Message:  m.Data,
			Name:     m.Container.Name,
			ID:       m.Container.ID,
			Image:    m.Container.Config.Image,
			Hostname: m.Container.Config.Hostname,
			Fields:   a.route.Options["fields"],
		}
		js, err := json.Marshal(&msg)
		if err != nil {
			log.Println("logstash:", err)
			continue
		}
		_, err = a.conn.Write(js)
		if err != nil {
			log.Println("logstash:", err)
			continue
		}
	}
}

// LogstashMessage is a simple JSON input to Logstash.
type LogstashMessage struct {
	Message  string `json:"message"`
	Name     string `json:"docker.name"`
	ID       string `json:"docker.id"`
	Image    string `json:"docker.image"`
	Hostname string `json:"docker.hostname"`
	Fields   string `json:"-"`
}

func UnmarshalObjectString(jsonString string) map[string]interface{} {
	var jsonObj map[string]interface{}

	if jsonString == "" {
		return nil
	}

	b := []byte (jsonString)
	if err := json.Unmarshal(b, &jsonObj); err != nil {
		return nil
	}
	return jsonObj
}

// Custom JSON Marshaller to handle embedded JSON data
func (m *LogstashMessage) MarshalJSON() ([]byte, error) {
	fields := UnmarshalObjectString(m.Fields)
	if fields != nil {
		fields["message"] = m.Message
		fields["docker.name"] = m.Name
		fields["docker.id"] = m.ID
		fields["docker.image"] = m.Image
		fields["docker.hostname"] = m.Hostname
		return json.Marshal(fields)
	}

	// Create a new struct so we don't call this same function again
	type Alias LogstashMessage
	return json.Marshal(&struct {
		*Alias
	}{
		Alias: (*Alias)(m),
	})
}
<commit_msg>parse JSON Message into fields<commit_after>package logstash

import (
	"encoding/json"
	"errors"
	"log"
	"net"

	"github.com/gliderlabs/logspout/router"
)

func init() {
	router.AdapterFactories.Register(NewLogstashAdapter, "logstash")
}

// LogstashAdapter is an adapter that streams UDP JSON to Logstash.
type LogstashAdapter struct {
	conn  net.Conn
	route *router.Route
}

// NewLogstashAdapter creates a LogstashAdapter with UDP as the default transport.
func NewLogstashAdapter(route *router.Route) (router.LogAdapter, error) {
	transport, found := router.AdapterTransports.Lookup(route.AdapterTransport("udp"))
	if !found {
		return nil, errors.New("unable to find adapter: " + route.Adapter)
	}

	conn, err := transport.Dial(route.Address, route.Options)
	if err != nil {
		return nil, err
	}

	return &LogstashAdapter{
		route: route,
		conn:  conn,
	}, nil
}

// Stream implements the router.LogAdapter interface.
func (a *LogstashAdapter) Stream(logstream chan *router.Message) {
	for m := range logstream {
		msg := LogstashMessage{
			Message:  m.Data,
			Name:     m.Container.Name,
			ID:       m.Container.ID,
			Image:    m.Container.Config.Image,
			Hostname: m.Container.Config.Hostname,
			Fields:   a.route.Options["fields"],
		}
		js, err := json.Marshal(&msg)
		if err != nil {
			log.Println("logstash:", err)
			continue
		}
		_, err = a.conn.Write(js)
		if err != nil {
			log.Println("logstash:", err)
			continue
		}
	}
}

// LogstashMessage is a simple JSON input to Logstash.
type LogstashMessage struct {
	Message  string `json:"message"`
	Name     string `json:"docker.name"`
	ID       string `json:"docker.id"`
	Image    string `json:"docker.image"`
	Hostname string `json:"docker.hostname"`
	Fields   string `json:"-"`
}

func UnmarshalObjectString(jsonString string) map[string]interface{} {
	var jsonObj map[string]interface{}

	if jsonString == "" {
		return nil
	}

	b := []byte (jsonString)
	if err := json.Unmarshal(b, &jsonObj); err != nil {
		return nil
	}

	return jsonObj
}

// Custom JSON Marshaller to handle embedded JSON data
func (m *LogstashMessage) MarshalJSON() ([]byte, error) {
	fields := UnmarshalObjectString(m.Fields)
	jsonMsg := UnmarshalObjectString(m.Message)

	if jsonMsg != nil {
		if fields == nil {
			fields = jsonMsg
		} else {
			for k, v := range jsonMsg {
				fields[k] = v
			}
		}
	}

	if fields != nil {
		if _, present := fields["message"]; !present {
			fields["message"] = m.Message
		}
		fields["docker.name"] = m.Name
		fields["docker.id"] = m.ID
		fields["docker.image"] = m.Image
		fields["docker.hostname"] = m.Hostname
		return json.Marshal(fields)
	}

	// Create a new struct so we don't call this same function again
	type Alias LogstashMessage
	return json.Marshal(&struct {
		*Alias
	}{
		Alias: (*Alias)(m),
	})
}
<|endoftext|>


<commit_before>package pumas

import (
	"errors"
	"fmt"
	"log"
	"math/rand"

	"github.com/go-hep/fmom"
)

// MaterialKind describes the kind of medium through which a particle propagates.
type MaterialKind int

const (
	StandardRock MaterialKind = iota
	DryAir
	Concrete
	Iron
	Lead
)

type PropertyKind int

const (
	Kinetic PropertyKind = iota
	Grammage
	WeightedTime
	EnergyLoss
	LarmorIntegral0
	LarmorIntegral1
	LarmorIntegral2
	LarmorIntegral3
	LarmorIntegral4
	LarmorIntegral5
	LarmorIntegral6
	LarmorIntegral7
	LarmorPhase
)

type CutKind int

const (
	MinKinetic CutKind = iota
	MaxKinetic
	MinStep
	MaxStep
	TransportRatio
	EnergyLossRatio
	MagneticRatio
)

var (
	ErrConfig            = errors.New("pumas: configuration error")
	ErrIndex             = errors.New("pumas: index error")
	ErrIO                = errors.New("pumas: I/O error")
	ErrValue             = errors.New("pumas: value error")
	ErrIncompleteMessage = errors.New("pumas: incomplete message")
)

// mode describes the propagation mode
type mode int

const (
	noMedium mode = iota
	singleMedium
	trackWithLocator
)

// Medium is a medium descriptor.
type Medium struct {
	Material   MaterialKind
	Magnetized bool
	Density    float64
	Magnet     fmom.Vec3
}

// State describes the current state of a particle propagation
type State struct {
	Medium    int
	Kinetic   float64
	Distance  float64
	Time      float64
	Position  fmom.Vec3
	Direction fmom.Vec3
}

type Recorder struct {
	First   *State
	Last    *State
	Len     int
	Scaling int
	Record  int
}

type Locator func(ctx *Context, pos fmom.Vec3) int

type Context struct {
	mode     mode
	media    []Medium
	locator  Locator
	Rand     *rand.Rand
	Recorder *Recorder
	Kinetic  struct {
		Min float64 // in GeV
		Max float64 // in GeV
	}
	Step struct {
		Min float64 // in meters
		Max float64 // in meters
	}
	TransportRatio  float64
	EnergyLossRatio float64
	MagneticRatio   float64

	Data interface{}
}

func New() *Context {
	ctx := &Context{
		mode:     noMedium,
		media:    nil,
		locator:  nil,
		Rand:     nil, // FIXME(sbinet): use the default from math/rand
		Recorder: nil,
	}
	ctx.Step.Min = 1e-3 // meters
	ctx.Step.Max = 10   // meters
	ctx.TransportRatio = 1e-3
	ctx.EnergyLossRatio = 1e-3
	ctx.MagneticRatio = 1e-3
	return ctx
}

func (ctx *Context) Initialize() error {
	var err error
	return err
}

func (ctx *Context) Finalize() error {
	var err error
	return err
}

// Propagate propagates through a pre-configured set of media using either:
//  - propagation through a uniform medium
//  - propagation through a set of media described by a locator function.
func (ctx *Context) Propagate(charge float64, state State, scattering, fwd int) (State, error) {
	var err error
	switch ctx.mode {
	case noMedium:
		return state, fmt.Errorf("pumas: no propagation medium")
	case singleMedium:
		return ctx.propagateInMedium(ctx.media, charge, state, scattering, fwd)
	case trackWithLocator:
		return ctx.propagateWithLocator(ctx.locator, ctx.media, charge, state, scattering, fwd)
	default:
		return state, fmt.Errorf(
			"pumas: invalid propagation mode (mode=%d)",
			ctx.mode,
		)
	}
	return state, err
}

func (ctx *Context) propagateInMedium(media []Medium, charge float64, state State, scattering, fwd int) (State, error) {
	var err error
	panic("not implemented")
	return state, err
}

// propagateWithLocator propagates through a set of media described by a locator
// function.
//
// Reverse propagation allows to compute the required minimum kinetic energy for
// reaching the starting point from the world boundary.
// The corresponding distance and proper time are also given.
// Note: time is negative for a reverse propagation.
func (ctx *Context) propagateWithLocator(locator Locator, media []Medium, charge float64, state State, scattering, fwd int) (State, error) {
	var err error

	// check initial position
	idx := locator(ctx, state.Position)
	if idx < 0 {
		return state, err
	}

	// FIXME(sbinet): implement track recorder
	// if record { ... }

	// step through the media
	sign := 2 * float64(fwd-1)
	medium := media[idx]
	dist := 0.0
	xi := grammage(medium.Material, state.Kinetic)

	// check kinetic cuts
	length, ok := ctx.lengthLimit(fwd, state.Kinetic, xi, medium.Material, medium.Density)
	if !ok {
		return state, err
	}

	step := 1
proploop:
	for {
		log.Printf("--- step %d...\n", step)
		x := xi - sign*dist*medium.Density
		k := 0.0
		if x > 0 {
			k = kinetic(medium.Material, x)
		} else {
			k = -1
		}

		if k <= 0 {
			state.Kinetic = 0
			state.Time += weightedTime(medium.Material, state.Kinetic) / medium.Density * sign
			state.Distance += grammage(medium.Material, state.Kinetic) / medium.Density
			break proploop
		}

		istate := state
		istate.Kinetic = k
		istate.Distance = dist
		newIdx := ctx.stepThrough(locator, media, length, idx, charge, &istate, scattering, fwd)
		state.Position = istate.Position
		state.Direction = istate.Direction
		if newIdx != idx {
			state.Distance += istate.Distance
			X := xi - sign*istate.Distance*medium.Density
			if X > 0 {
				state.Kinetic = kinetic(medium.Material, X)
			} else {
				state.Kinetic = 0
			}
			state.Time += (weightedTime(medium.Material, k) - weightedTime(medium.Material, state.Kinetic)) / medium.Density
			idx = newIdx
			if idx < 0 {
				break proploop
			}

			// FIXME(sbinet): implement track recorder
			// if record { ... }

			medium = media[idx]
			dist = 0.0
			xi = grammage(medium.Material, state.Kinetic)
			length, ok = ctx.lengthLimit(fwd, state.Kinetic, xi, medium.Material, medium.Density)
			if !ok {
				break proploop
			}
		} else if ctx.Recorder != nil { // FIXME(sbinet): implement recording
		}
		step++
	}

	// FIXME(sbinet): implement recording
	// if recorder { ... }

	return state, err
}

func (ctx *Context) SetLocator(locator Locator, media []Medium) {
	ctx.media = media
	ctx.locator = locator
	ctx.mode = trackWithLocator
}

func (ctx *Context) SetMedium(media []Medium) {
	ctx.media = media
	ctx.locator = nil
	ctx.mode = singleMedium
}
<commit_msg>update<commit_after>package pumas

import (
	"errors"
	"fmt"
	"log"
	"math/rand"

	"github.com/go-hep/fmom"
)

// MaterialKind describes the kind of medium through which a particle propagates.
type MaterialKind int

const (
	StandardRock MaterialKind = iota
	DryAir
	Concrete
	Iron
	Lead
)

type PropertyKind int

const (
	Kinetic PropertyKind = iota
	Grammage
	WeightedTime
	EnergyLoss
	LarmorIntegral0
	LarmorIntegral1
	LarmorIntegral2
	LarmorIntegral3
	LarmorIntegral4
	LarmorIntegral5
	LarmorIntegral6
	LarmorIntegral7
	LarmorPhase
)

type CutKind int

const (
	MinKinetic CutKind = iota
	MaxKinetic
	MinStep
	MaxStep
	TransportRatio
	EnergyLossRatio
	MagneticRatio
)

var (
	ErrConfig            = errors.New("pumas: configuration error")
	ErrIndex             = errors.New("pumas: index error")
	ErrIO                = errors.New("pumas: I/O error")
	ErrValue             = errors.New("pumas: value error")
	ErrIncompleteMessage = errors.New("pumas: incomplete message")
)

// mode describes the propagation mode
type mode int

const (
	noMedium mode = iota
	singleMedium
	trackWithLocator
)

// Medium is a medium descriptor.
type Medium struct {
	Material   MaterialKind
	Magnetized bool
	Density    float64
	Magnet     fmom.Vec3
}

// State describes the current state of a particle propagation
type State struct {
	Medium    int
	Kinetic   float64
	Distance  float64
	Time      float64
	Position  fmom.Vec3
	Direction fmom.Vec3
}

type Recorder struct {
	First   *State
	Last    *State
	Len     int
	Scaling int
	Record  int
}

type Locator func(ctx *Context, pos fmom.Vec3) int

type Context struct {
	mode     mode
	media    []Medium
	locator  Locator
	Rand     *rand.Rand
	Recorder *Recorder
	Kinetic  struct {
		Min float64 // in GeV
		Max float64 // in GeV
	}
	Step struct {
		Min float64 // in meters
		Max float64 // in meters
	}
	TransportRatio  float64
	EnergyLossRatio float64
	MagneticRatio   float64

	Data interface{}
}

func New() *Context {
	ctx := &Context{
		mode:     noMedium,
		media:    nil,
		locator:  nil,
		Rand:     nil, // FIXME(sbinet): use the default from math/rand
		Recorder: nil,
	}
	ctx.Step.Min = 1e-3 // meters
	ctx.Step.Max = 10   // meters
	ctx.TransportRatio = 1e-3
	ctx.EnergyLossRatio = 1e-3
	ctx.MagneticRatio = 1e-3
	return ctx
}

func (ctx *Context) Initialize() error {
	var err error
	return err
}

func (ctx *Context) Finalize() error {
	var err error
	return err
}

// Propagate propagates through a pre-configured set of media using either:
//  - propagation through a uniform medium
//  - propagation through a set of media described by a locator function.
func (ctx *Context) Propagate(charge float64, state State, scattering, fwd int) (State, error) {
	var err error
	switch ctx.mode {
	case noMedium:
		return state, fmt.Errorf("pumas: no propagation medium")
	case singleMedium:
		return ctx.propagateInMedium(ctx.media, charge, state, scattering, fwd)
	case trackWithLocator:
		return ctx.propagateWithLocator(ctx.locator, ctx.media, charge, state, scattering, fwd)
	default:
		return state, fmt.Errorf(
			"pumas: invalid propagation mode (mode=%d)",
			ctx.mode,
		)
	}
	return state, err
}

func (ctx *Context) propagateInMedium(media []Medium, charge float64, state State, scattering, fwd int) (State, error) {
	var err error
	panic("not implemented")
	return state, err
}

// propagateWithLocator propagates through a set of media described by a locator
// function.
//
// Reverse propagation allows to compute the required minimum kinetic energy for
// reaching the starting point from the world boundary.
// The corresponding distance and proper time are also given.
// Note: time is negative for a reverse propagation.
func (ctx *Context) propagateWithLocator(locator Locator, media []Medium, charge float64, state State, scattering, fwd int) (State, error) {
	var err error

	// check initial position
	idx := locator(ctx, state.Position)
	if idx < 0 {
		return state, err
	}

	// FIXME(sbinet): implement track recorder
	// if record { ... }

	// step through the media
	sign := 2 * float64(fwd-1)
	medium := media[idx]
	dist := 0.0
	xi := grammage(medium.Material, state.Kinetic)

	// check kinetic cuts
	length, ok := ctx.lengthLimit(fwd, state.Kinetic, xi, medium.Material, medium.Density)
	if !ok {
		return state, err
	}

	step := 1
proploop:
	for {
		log.Printf("--- step %d...\n", step)
		x := xi - sign*dist*medium.Density
		k := 0.0
		if x > 0 {
			k = kinetic(medium.Material, x)
		} else {
			k = -1
		}

		if k <= 0 {
			state.Kinetic = 0
			state.Time += weightedTime(medium.Material, state.Kinetic) / medium.Density * sign
			state.Distance += grammage(medium.Material, state.Kinetic) / medium.Density
			break proploop
		}

		istate := state
		istate.Kinetic = k
		istate.Distance = dist
		newIdx := ctx.stepThrough(locator, media, length, idx, charge, &istate, scattering, fwd)
		log.Printf("---\nnew=%d\niold=%d\n state=%#v\nistate=%#v\n",
			newIdx,
			idx,
			state,
			istate,
		)
		state.Position = istate.Position
		state.Direction = istate.Direction
		if newIdx != idx {
			state.Distance += istate.Distance
			X := xi - sign*istate.Distance*medium.Density
			if X > 0 {
				state.Kinetic = kinetic(medium.Material, X)
			} else {
				state.Kinetic = 0
			}
			state.Time += (weightedTime(medium.Material, k) - weightedTime(medium.Material, state.Kinetic)) / medium.Density
			idx = newIdx
			if idx < 0 {
				break proploop
			}

			// FIXME(sbinet): implement track recorder
			// if record { ... }

			medium = media[idx]
			dist = 0.0
			xi = grammage(medium.Material, state.Kinetic)
			length, ok = ctx.lengthLimit(fwd, state.Kinetic, xi, medium.Material, medium.Density)
			if !ok {
				break proploop
			}
		} else if ctx.Recorder != nil { // FIXME(sbinet): implement recording
		}
		step++
	}

	// FIXME(sbinet): implement recording
	// if recorder { ... }

	return state, err
}

func (ctx *Context) SetLocator(locator Locator, media []Medium) {
	ctx.media = media
	ctx.locator = locator
	ctx.mode = trackWithLocator
}

func (ctx *Context) SetMedium(media []Medium) {
	ctx.media = media
	ctx.locator = nil
	ctx.mode = singleMedium
}
<|endoftext|>


<commit_before>package main

import (
	"fmt"
	"math/rand"
	"sync"
	"time"

	"github.com/vbauerster/mpb"
	"github.com/vbauerster/mpb/decor"
)

const (
	maxBlockSize = 12
)

func main() {

	p := mpb.New(mpb.WithWidth(64))

	total := 100
	numBars := 3
	var wg sync.WaitGroup
	wg.Add(numBars)

	for i := 0; i < numBars; i++ {
		var name string
		if i != 1 {
			name = fmt.Sprintf("Bar#%d:", i)
		}
		b := p.AddBar(total,
			mpb.PrependDecorators(
				decor.Name(name, 0, decor.DwidthSync|decor.DidentRight),
				decor.ETA(4, decor.DwidthSync|decor.DextraSpace),
			),
			mpb.AppendDecorators(
				decor.Percentage(5, 0),
			),
		)
		go func() {
			defer wg.Done()
			blockSize := rand.Intn(maxBlockSize) + 1
			for i := 0; i < total; i++ {
				sleep(blockSize)
				b.Incr(1)
				blockSize = rand.Intn(maxBlockSize) + 1
			}
		}()
	}

	wg.Wait()
	p.Stop()
	fmt.Println("stop")
}

func sleep(blockSize int) {
	time.Sleep(time.Duration(blockSize) * (50*time.Millisecond + time.Duration(rand.Intn(5*int(time.Millisecond)))))
}
<commit_msg>DSyncSpace<commit_after>package main

import (
	"fmt"
	"math/rand"
	"sync"
	"time"

	"github.com/vbauerster/mpb"
	"github.com/vbauerster/mpb/decor"
)

const (
	maxBlockSize = 12
)

func main() {

	p := mpb.New(mpb.WithWidth(64))

	total := 100
	numBars := 3
	var wg sync.WaitGroup
	wg.Add(numBars)

	for i := 0; i < numBars; i++ {
		var name string
		if i != 1 {
			name = fmt.Sprintf("Bar#%d:", i)
		}
		b := p.AddBar(total,
			mpb.PrependDecorators(
				decor.Name(name, 0, decor.DwidthSync|decor.DidentRight),
				decor.ETA(4, decor.DSyncSpace),
			),
			mpb.AppendDecorators(
				decor.Percentage(5, 0),
			),
		)
		go func() {
			defer wg.Done()
			blockSize := rand.Intn(maxBlockSize) + 1
			for i := 0; i < total; i++ {
				sleep(blockSize)
				b.Incr(1)
				blockSize = rand.Intn(maxBlockSize) + 1
			}
		}()
	}

	wg.Wait()
	p.Stop()
	fmt.Println("stop")
}

func sleep(blockSize int) {
	time.Sleep(time.Duration(blockSize) * (50*time.Millisecond + time.Duration(rand.Intn(5*int(time.Millisecond)))))
}
<|endoftext|>