text:
---
title: Automating with Packer and TerraForm
date: 2016-10-13T08:10:00.000Z
description: Automating infrastructure with Packer and Terraform
image: /images/uploads/terraform.png
---

[![Po.et verification](https://img.shields.io/badge/Po.et-Verified%20on%20Po.et-green.svg)](https://explorer-mainnet.poetnetwork.net/works/64c8a3722898343c19e58004929114983aa1c5fef4fd655eff9c21028d3f9e9d)

# Automating with Packer and TerraForm

[Hashicorp](https://www.hashicorp.com/) have created some amazing tools to help engineers in orchestrating cloud architecture. Two tools I want to go through are [Packer](https://www.packer.io/) and [TerraForm](https://www.terraform.io)

### [Packer.io](https://www.packer.io/)

#### So what exactly is packer
> Packer is an open source tool for creating identical machine images for multiple platforms from a single source configuration. Packer is lightweight, runs on every major operating system, and is highly performant, creating machine images for multiple platforms in parallel. Packer does not replace configuration management like Chef or Puppet. In fact, when building images, Packer is able to use tools like Chef or Puppet to install software onto the image.

> A machine image is a single static unit that contains a pre-configured operating system and installed software which is used to quickly create new running machines. Machine image formats change for each platform. Some examples include AMIs for EC2, VMDK/VMX files for VMware, OVF exports for VirtualBox, etc.

Pre-baked machine images open up a lot in terms of delivery of infrastructure in the modern dev environment. Having the ability to achieve near identical environments running on different providers, can add a world of benefit to any development pipeline. Packer makes this process simple and efficient.

* Super fast infrastructure deployment
* ulti-provider portability
* Improved stability
* Greater testability

### [Terraform](https://www.terraform.io/)

#### So what is TerraForm?

> Terraform is a tool for building, changing, and versioning infrastructure safely and efficiently. Terraform can manage existing and popular service providers as well as custom in-house solutions.

> Configuration files describe to Terraform the components needed to run a single application or your entire datacenter. Terraform generates an execution plan describing what it will do to reach the desired state, and then executes it to build the described infrastructure. As the configuration changes, Terraform is able to determine what changed and create incremental execution plans which can be applied.

### Why use both?

Packer's ability to generate machines images for various builders, means we can create near identical machines across multiple platforms and environments.

TerraFormcan then take the machine image artifacts from Packer, and create the actual resources we need in our infrastructure. This greatly helps us avoid vendor lock-in, as well as ensure that our architecture is provisioned accurately, and quickly, and multiple environments of the architecture can be created seamlessly with minimal effort.

### Infrastructure as Code

Tools such as Packer and TerraForm form part of what is to be knowns as Infrastructure as Code.

> Infrastructure as Code (IaC) is the process of managing and provisioning computing infrastructure (processes, bare-metal servers, virtual servers, etc.) and their configuration through machine-processable definition files

IaC should not be confused with configuration management. IaC is not a substitute, but should implemented in to you orchestration processes along with your configuration management tools.

> Ensure you have the Packer and Terraform binaries installed on your pc.

### Getting Stuck in

A more complete example of Packer and TerraForm can be found [here](https://github.com/WesleyCharlesBlake/terraform-existing-vpc)

In Packer, your definitions are declared in a `.json` template file. I prefer to name my templates based on their purpose (eg: `app-base.json`)

Lets look at the structure of the template (create an empty file `nano myfirst-packer.json` and add the following resources to your template:

```bash
{
  "builders": [],
  "description": "A packer example template",
  "min_packer_version": "0.8.0",
  "provisioners": [],
  "post-processors": [],
  "variables": []
}
```

Packer needs to be told what to do, where to do it, provision any other boostrapping requirements etc. What does this mean:

`"builders": [],`:
> the builders section contains an array of all the builders that Packer should use to generate a machine images for the template. Builders are responsible for creating machines and generating images from them for various platforms. For example, there are separate builders for EC2, VMware, VirtualBox, etc. Packer comes with many builders by default, and can also be extended to add new builders.

`"provisioners":`
> he provisioners section contains an array of all the provisioners that Packer should use to install and configure software within running machines prior to turning them into machine images.Provisioners are optional. If no provisioners are defined within a template, then no software other than the defaults will be installed within the resulting machine images. This is not typical, however, since much of the value of Packer is to produce multiple identical images of pre-configured software.

`"post-processors":`
> The post-processor section within a template configures any post-processing that will be done to images built by the builders. Examples of post-processing would be compressing files, uploading artifacts, etc.Post-processors are optional. If no post-processors are defined within a template, then no post-processing will be done to the image. The resulting artifact of a build is just the image outputted by the builder.

`"variables":`
> variables allow your templates to be further configured with variables from the command-line, environment variables, or files. This lets you parameterize your templates so that you can keep secret tokens, environment-specific data, and other types of information out of your templates. This maximizes the portability and shareability of the template.

So lets update our template with some builders, provisioners, and variables:

```bash
{
  "variables": {
      "aws_access_key": "YOURACCESSKEY",
      "aws_secret_key": "YOURSECRETKEY",
      "do_api_token": "YOURAPITOKEN"
  },
  "builders": [{
      "type": "amazon-ebs",
      "access_key": "{{user `aws_access_key`}}",
      "secret_key": "{{user `aws_secret_key`}}",
      "region": "us-east-1",
      "source_ami": "ami-fce3c696",
      "instance_type": "t2.micro",
      "ssh_username": "ubuntu",
      "ami_name": "packer-example {{timestamp}}"
  },{
    "type": "digitalocean",
        "api_token": "{{user `do_api_token`}}",
        "image": "ubuntu-14-04-x64",
        "region": "nyc3",
        "size": "512mb"
  }],
  "provisioners": [{
      "type": "shell",
          "inline": [
              "sleep 30",
              "sudo apt-get update",
              "sudo apt-get install -y redis-server"
    ]
  }]
}
```

The template will not build an AWS AMI, as well as a DigitalOcean snapshot, with the `redis-server` installed. This is very basic, but its upto you to decide how much you want bake into your image, and how much you want to rely on configuration management. This balance is entirely up to your infrastructure/application and deployment requirements.

A more complex provisioner could look like this:

```bash
"provisioners": [
    {
      "type": "shell",
      "inline": [
        "sudo wget -O - https://repo.saltstack.com/apt/debian/8/amd64/latest/SALTSTACK-GPG-KEY.pub | sudo apt-key add -",
        "sudo su -c 'echo \"deb http://repo.saltstack.com/apt/debian/8/amd64/latest jessie main\" >> /etc/apt/sources.list'",
        "sudo apt-get update",
        "sudo apt-get install -y software-properties-common",
        "sudo apt-get install -y build-essential git",
        "sudo apt-get install -y python python-dev python-setuptools",
        "sudo apt-get install -y salt-minion",
        "sudo apt-get install -y virtualenv",
        "sudo apt-get install -y virtualenvwrapper",
        "sudo wget https://bootstrap.pypa.io/get-pip.py",
        "sudo python get-pip.py",
        "sudo pip install ansible",
      ]
    },
    {
      "type": "salt-masterless",
      "skip_bootstrap": "true",
      "local_state_tree": "/path/to/salt",
      "minion_config" : "/path/to/salt/salt/minion"
    }
    ],
```

This provisioner installs my application build dependencies, installs `salt-minion`, install `virtual-env` and `python pip` and also installs `ansible` (yes, I have a very strange config management strategy, but it works for our use case).

So with these provisioners in the bootstrapping stage, I then can use TerraForm to create the salt-minion ids and keys on creation, and have the salt master register the newly created resource. By baking all the build packages in, I know that each resource created from the image will be concurrent. It helps create a better Dev/Prod parity ("it works on my machine?" excuses ring any bells ;).

To run build your image, packer has some validation tools to help you:

`packer validate myfirst-packer.json`: check that a template is valid (json/syntax errors)

`packer inspect myfirst-packer.json`: see components of a template. This is helpful if you want to see what the output/resources of a template with out having to run a build.

`packer build myfirst-packer.json`: build image(s) from template. If you have multiple builders in your template, the builds will run in parallel (AWESOME!)

`packer fix myfirst-packer.json`: fixes templates from old versions of packer. This is important if you working in a team, and want to ensure the template is the correct version for the version of packer you are running.

### So now that we are building images with Packer, lets use them in TerraForm

Please visit their [site](https://www.terraform.io/downloads.html) and ensure you have TerraForm installed before proceeding.

> Configuration files describe to Terraform the components needed to run a single application or your entire datacenter. Terraform generates an execution plan describing what it will do to reach the desired state, and then executes it to build the described infrastructure. As the configuration changes, Terraform is able to determine what changed and create incremental execution plans which can be applied.

> The infrastructure Terraform can manage includes low-level components such as compute instances, storage, and networking, as well as high-level components such as DNS entries, SaaS features, etc.

For this exmample, we are going to use TerraForm to build infrastructure on AWS.

Lets create a basic TerraForm template: `nano example.tf`:

```bash
provider "aws" {
  access_key = "ACCESS_KEY_HERE"
  secret_key = "SECRET_KEY_HERE"
  region     = "us-east-1"
}

resource "aws_instance" "example" {
  ami           = "ami-0d729a60" #use ami from packer build
  instance_type = "t2.micro"
}
```

Two most important parts of a TF file are `providers` and `resource` blocks. These essentially tell TerraForm where to build (provider), and what to build (resource). Multiple resource blocks make up your infrastructure (eg you would want a resource block for ec2 resources, another resource block for an elb resource, and so on)

If we are using custom AMIS's (as built by our own packer templates), we would want to use the out put ami id from Packer, in our EC2 resource block in TerraForm. This way TerraForm will use our freshly baked AMI to create the resources. Im sure you can see why this would be handy!

TerraForm's documention is very comprehensive, so go through each resource you are trying to create to get a better understanding.

> Note: You can create a count variable in your resource block, and create n resources from this!

### Plan

Lets plan an execution with TerraForm. In the same directory as your TerraForm template run `terraform plan`. You will see an out put of all the resources that TerraForm would create (without actually creating it!):

```bash
$ terraform plan
...

+ aws_instance.example
    ami:                      "ami-0d729a60"
    availability_zone:        "<computed>"
    ebs_block_device.#:       "<computed>"
    ephemeral_block_device.#: "<computed>"
    instance_state:           "<computed>"
    instance_type:            "t2.micro"
    key_name:                 "<computed>"
    placement_group:          "<computed>"
    private_dns:              "<computed>"
    private_ip:               "<computed>"
    public_dns:               "<computed>"
    public_ip:                "<computed>"
    root_block_device.#:      "<computed>"
    security_groups.#:        "<computed>"
    source_dest_check:        "true"
    subnet_id:                "<computed>"
    tenancy:                  "<computed>"
    vpc_security_group_ids.#: "<computed>"
```

If you are happy with out put, you can run plan, alternatively you may need to fix any errors etc. You might also want to store the out put of plan, in order run the execution. There are benefits of storing the plan output

### Apply

Run `terraform apply` in the same directory as your example.tf to create the resources!

You should see something like this:

```bash
$ terraform apply
aws_instance.example: Creating...
  ami:                      "" => "ami-0d729a60"
  instance_type:            "" => "t2.micro"
  [...]

aws_instance.example: Still creating... (10s elapsed)
aws_instance.example: Creation complete

Apply complete! Resources: 1 added, 0 changed, 0 destroyed.

...
```

TerraForm is busy creating your resources!

### State

An important concept to be aware of is state.

Terraform also put some state into the terraform.tfstate file by default. This state file is extremely important; it maps various resource metadata to actual resource IDs so that Terraform knows what it is managing. This file must be saved and distributed to anyone who might run Terraform. We recommend simply putting it into version control, since it generally isn't too large.

You can inspect the state using `terraform show`:

```bash
$ terraform show
aws_instance.example:
  id = i-32cf65a8
  ami = ami-0d729a60
  availability_zone = us-east-1a
  instance_state = running
  instance_type = t2.micro
  private_ip = <IP_ADDRESS>
  public_dns = ec2-52-90-212-55.compute-1.amazonaws.com
  public_ip = <IP_ADDRESS>
  subnet_id = subnet-1497024d
  vpc_security_group_ids.# = 1
  vpc_security_group_ids.3348721628 = sg-67652003
```

To destroy resources, you could run `terraform destroy` and it will handle the rest.

> Note: be aware of resources changes that require the resource to be destroyed and recreated. Changing an AWS EC2 resource AMI to something new, means the old EC2 images will be destroyed and recreated. Besure to plan these changes correctly, or you could have a very bad day.

Thats it for now! If you have any questions give me a shout!

I hope this helps you understand Packer and TerraForm a bit better.

gha_language: CSS


text:
---
layout: archive
title: "Hao Yu"
permalink: /resume/
author_profile: true
header:
  image: "/images/about.jpeg"
---

## Education

Mills College

    Oakland, CA

MA, Interdisciplinary Computer Science (Expected, May 2019) GPA: 3.9/4.0

Coursework: Machine Learning, Intro to Data Analysis, Theory of Algorithms, Computer Graphics, iOS Development with Swift, Programming Languages, Discrete Math, Computer Architecture

Northwestern Polytechnic University GPA: 4.0/4.0

    Fremont, CA

Coursework: Data Structures and Algorithms, Computer Network, Unix/Linux Shell and Python Scripting, Oracle Database administration (SQL), SAS, Socket Programming in C

Central University of Finance and Economics

    Beijing, China

BA, Economics, Insurance Major (Conferred June 2015)

## Experience

Teaching Assistant of Google Applied Machine Intensive(AMLI)

    AMLI is an intensive 10 weeks (40 hours per week) Bootcamp
    Feb. 2019 - Apr. 2019

Co-design and TA for the AMLI pilot hosted by Google EngEDU division at Mills College

Revise coding exercises and lecture materials to meet students’ knowledge level and needs

Host daily office hours and help resolve student questions

Grade student submissions and provide feedback

Graduate Teaching Assistant / Peer Tutor

    Mills College, Oakland, CA

Holding weekly office hour for student questions.

Grade student submissions.

Spring 2019 : CS125 / CS225 Theory of Algorithms

Fall 2018: Discrete Math and Data Structures

Fall 2017: Discrete Math II

Lab Instructor of C++ Programming and Oracle Database

    NPU, Fremont, CA
    Apr. 2016 – Jan. 2017

Prepared weekly lab syllabus and handouts, conducted short lecture and answered questions.

Prepared and graded lab homework, quizzes, exams.

Skills

TensorFlow, Machine Learning algorithms

Operating Systems: Unix/Linux, Windows, Macintosh

Coding: Python, Java, SAS, C++, C, SQL, Swift, OpenGL

Development Tools: Eclipse, NetBeans, Bash, Git, PyCharm, SAS Studio

Language: Fluent in English, Mandarin

Honors and Achievements

SAS Certified Base Programmer for SAS 9

Mills College 2017 Hackathon winner (Project: FoodDrop App prototype)

CASPA 2017 Annual Conference Volunteer

2017 Fremont 4th of July Parade Student Volunteer

license: MIT

branch_name: refs/heads/master

extension: md

license_type: permissive


text:
# Available RCS Storage

## High Performance Computing Storage

High Performance Computing storage \($CENTER1\) is fast, high throughput, scratch storage available to Chinook users. $CENTER1 is a Lustre filesystem best used for large files. Reading or writing many small files may result in a noticeable performance reduction. As a scratch workspace, data in $CENTER1 is not backed up. Files that need long-term storage should be copied to a different system or filesystem, such as $ARCHIVE.

Projects are subject to a quota in $CENTER1. Quotas may be checked using the “show\_storage” command. Always check to see if there is storage available for your file to be written as files written that go over the quota may be truncated, unwritten, or block move and write access to the filesystem.

Subsidized quota: 1 TB

## Online Spinning Disk

Online spinning disk is used to share data and storage to RCS managed VMs. Data may be backed up automatically to $ARCHIVE for an additional service fee or Principal Investigators may back up online spinning disk data manually to their $ARCHIVE account using their subsidized 10 TB or any additional purchased $ARCHIVE storage. Online spinning disk storage will generally perform slower when used with high performance computing.

## Offline Tape Archive

The offline tape archive \($ARCHIVE\) is a long-term storage solution for infrequently accessed data, such as retention of completed work or an archive of data. Data stored in $ARCHIVE is written out to magnetic tape and must be retrieved when copied to another filesystem, resulting in very slow access times. Files in $ARCHIVE should be copied or moved to another filesystem before modifying or using the files.

Principal Investigators in $ARCHIVE are subject to quota. When quota is reached files may no longer be written, and a file that is currently being written to the filesystem may be truncated or deleted, and access to writing and moving files may be lost. It is always recommended to check that there is enough space to write your file. Quotas and current usage can be viewed with the “show\_storage” command.

Subsidized quota: 10 TB

## Restricted Data Services

Launching in Spring 2020

Restricted data services are for data with specific data guidelines such as NIST or ITAR requirements, and cover file sharing and additional online spinning disk and $ARCHIVE storage. The restricted file share is available at no cost to UA faculty, staff, and students, but all data will be purged after 60 days. Restricted $ARCHIVE is subsidized at 2 TB, and additional restricted online spinning disk and $ARCHIVE can be purchased according to RCS service rates.

If you are unsure if a project's data needs require the restricted data service, please contact RCS \([uaf-rcs@alaska.edu](mailto:uaf-rcs@alaska.edu)\).

repository: UAF-RCS/uaf-rcs-storage-docs

repo_name: UAF-RCS/uaf-rcs-storage-docs


text:
boilerplate
===========

This is a starting point for my projects. Boilerplate code for different scenarios is in different branches.

This boilerplate is MIT-licensed, as well as the projects it’s used for. So feel free to use it if you want.

Usage
-----

1) Clone this repository:

```sh
$ git clone git@github.com:tomekwi/boilerplate <my project name>
```

2) Bootstrap:

```sh
$ git checkout <boilerplate flavor – I normally go for `javascript`>
$ ./_boilerplate.fish <name> <description> [<title> [<repo>]]
```

3) Push your way forward!

```sh
$ git push --set-upstream origin master
```


text:
---
layout: post
title: Where to Buy ZLD?
date: 2018-08-02
author:
  name: Yegor Bugayenko
  twitter: yegor256
description: |
  When you buy Zold, you donate your money to the open source
  segment of the software development, supporting the
  management revolution.
tags: blockchain
---

Zold is a cryptocurrency with a [mission]({% post_url 2018/07/2018-07-08-mission %}).
It doesn't have Airdrop or Bounty programs.
We created it as a catalyst for the revolution of software development industry, [Zerocracy](https://www.zerocracy.com) is leading.
There are only three four possible ways to get ZLD.

First, you can fund any **sandbox** project managed by [Zerocrat](https://www.yegor256.com/2018/03/21/zerocracy-announcement.html) and get the equivalent amount of ZLD, according to the Exchange Rate at the moment of the contribution. Say, donate $32 and immediately get about 11 ZLD to your [web wallet](https://wts.zold.io) (1 ZLD = $2.95, at the moment of writing). We will identify you by your GitHub user name. Check out the projects [Board](https://www.0crat.com/board) and look for those with the "sandbox" badge.

You can even donate to Zold Ruby core project itself, just click this
button and pay via Stripe:

Second, you can instantly convert your bitcoins to zold
as [explained]({% post_url 2018/12/2018-12-09-btc-to-zld %}), just start
[here](https://wts.zold.io/quick) (you will be authenticated via mobile phone).

Third, you can [join](https://www.0crat.com/join) one of the projects
managed by Zerocrat as a programmer and receive ZLD for the tasks completed.
At the moment we give away ZLD as a bonus on top of every dollar you make
in Zerocracy. If you are a [good](https://www.yegor256.com/2018/07/24/bugs-or-pull-requests.html)
and disciplined programmer, you will make
a few 2-3 thousand US dollars (in ZLD) every months, working part-time.

Fourth, you can host your own Zold node and collect taxes and hosting bonuses.
[This page](https://github.com/zold-io/zold) explains how to do that.

Fifth, you can buy ZLD at [AlterDice]({% post_url 2019/04/2019-04-17-alterdice %}),
the first crypto exchange that lists our coin.

gha_language: HTML

gha_license_id: MIT


text:
---
layout: default
title: refreshAndWait()
parent: web
tags: command web
comments: true
---

### Description

- This command will refresh the active browser and wait for 30 seconds.
- In other words the command will refresh the browser and wait for 30 seconds.
- The command will refresh and pass if active browser found or else fail otherwise.
- No input parameter required for this command

### Parameters

### Example

**Script**:

![](image/refreshAndWait_01.png)

**Output**:

![](image/refreshAndWait_02.png)

### See Also

- [`open(url)`](open(url))
- [`refresh()`](refresh())
- [`web`](index)

repository: cyrilbois/documentation

repo_name: cyrilbois/documentation


text:
# Challenge 04 - Continuous Integration (CI) - Coach's Guide

[< Previous Solution](./Solution-03.md) - **[Home](./README.md)** - [Next Solution >](./Solution-05.md)

## Notes & Guidance

- See solution, in solutions folder for GitHub Action Workflow file.

## Solution
- [Navigate to Solution for Challenge 04](./Solution/Solution-04/Solution04.yml)

repository: gfilicetti/WhatTheHack

repo_name: gfilicetti/WhatTheHack


text:
# no-rest-for-weary
Keep a free tier heroku app from sleeping

Assumptions
- You have Chrome browser installed on your machine
- You have a recent python 3 release

Steps
1. Clone the repo to your environment
2. Create a virtual environment
    ```python
    python -m venv env
    ```
3. Install req's
    ```python
    pip install -r requirements.txt
    ```
4. Edit the virtual environment activation script location in workflow.sh
5. Edit the url in browser.get(...) within bot.py. This should be the url of your heroku app
6. If not on a Mac OS, modify the workflow.sh script as needed for your OS
7. Add the workflow.sh script to crontab or systemd depending


text:
---
layout: post
status: publish
published: true
title: Running Jenkins using SMF on Solaris 11
author: Andrew Kroh
date: '2011-06-28 01:16:34 -0400'
date_gmt: '2011-06-28 05:16:34 -0400'
categories:
- Solaris
tags:
- solaris11
---

Jenkins (formerly known as Hudson) is a continuous integration tool. Installing
Jenkins as a daemon service on Solaris 11 is pretty simple. Below are the steps
I took to get it up and running using SMF in Solaris 11. SMF or Service
Management Facility is the default way to manage services in Solaris 10 and 11.

#### Create New User to Run Jenkins

```
groupadd jenkins
useradd -g jenkins -d /export/home/jenkins -m -s /bin/bash jenkins
passwd jenkins
```

Configure the User’s Environment

```
sudo su - jenkins
mkdir workspace
wget http://mirrors.jenkins-ci.org/war-stable/latest/jenkins.war
echo source .bashrc > .bash_profile
```

Create a .bashrc with the appropriate settings for your jenkins user.

{% highlight bash %}
# Define default prompt to <username>@<hostname>:<path><"($|#) ">
# and print '#' for user "root" and '$' for normal users.
#
typeset +x PS1="\u@\h:\w\\$ "
alias l='ls -lah'
alias cdh='cd ~'

# CVS over SSH Configuration (assuming local server)
host=`hostname`
export CVS_RSH=ssh
export CVSROOT=:ext:jenkins@$host:/var/cvs

# Gradle Options
GRADLE_OPTS="-Dorg.gradle.daemon=true"
{% endhighlight %}

Create a start_jenkins.sh script.

{% highlight bash %}
#!/bin/sh
source /export/home/jenkins/.bashrc
HTTP_HOST="<IP_ADDRESS>"
HTTP_PORT="7777"

export JENKINS_HOME=/export/home/jenkins/workspace

java -Dmail.smtp.starttls.enable=true -jar /export/home/jenkins/jenkins.war --prefix=/jenkins --httpListenAddress=$HTTP_HOST --httpPort=$HTTP_PORT
{% endhighlight %}

Add execute permissions to the new script.

{% highlight bash %}
chmod a+x start_jenkins.sh
{% endhighlight %}

#### Configure SSH to allow CVS only for Jenkins

Generate a SSH key for jenkins.

{% highlight bash %}
cd ~/.ssh
ssh-keygen -t dsa
{% endhighlight %}

Append the contents of id_dsa.pub to the ~/.ssh/authorized_keys2 file on the system
that you want to allow you to log in to.

Add `command="/usr/bin/cvs server",no-port-forwarding,no-X11-forwarding,no-agent-forwarding"`
to the beginning of the line you just appended to limit the commands that Jenkins can
execute when SSH’ing to the server.

Test your SSH connection once so that you can accept the server’s key or else
Jenkins will hang on the first CVS checkout.

#### Configure SMF to Start Jenkins as a Service

You need to load a manifest file into SMF that tells it how to run Jenkins.
Place the following manifest file in `/var/svc/manifest/application` and then
load it into SMF using svccfg.

Listing: `/var/svc/manifest/application/jenkins.xml`

{% highlight xml %}
<?xml version='1.0'?>

<!DOCTYPE service_bundle SYSTEM '/usr/share/lib/xml/dtd/service_bundle.dtd.1'>

<service_bundle type="manifest" name="Jenkins">
    <service name="application/jenkins" type="service" version="1">
       <create_default_instance enabled="false"/>
       <single_instance/>

       <method_context>
           <method_credential user='jenkins' group='jenkins'/>

           <method_environment>
               <envvar name='PATH' value='/usr/bin:/usr/local/bin'/>
           </method_environment>
       </method_context>

       <exec_method type="method" name="start" exec="/export/home/jenkins/start_jenkins.sh" timeout_seconds="0"/>

       <exec_method type="method" name="stop" exec=":kill -TERM" timeout_seconds="30"/>

       <property_group name='startd' type='framework'>
           <propval name='duration' type='astring' value='child'/>
       </property_group>

       <stability value="Evolving"/>

       <template>
           <common_name>
               <loctext xml:lang='C'>Jenkins Continuous Build Server</loctext>
           </common_name>

           <documentation>
               <doc_link name='jenkins-ci.org' uri='http://jenkins-ci.org/'/>
           </documentation>
       </template>
    </service>
</service_bundle>
{% endhighlight %}

Now with the manifest file on your system. It’s time to load it into SMF.

{% highlight bash %}
svcadm restart svc:/system/manifest-import
svcadm enable jenkins
{% endhighlight %}

You can verify that it started by running this command and checking the state.

{% highlight bash %}
$ svcs -l jenkins
fmri svc:/application/jenkins:default
name Jenkins Continuous Build Server
enabled true
state online
next_state none
state_time June 28, 2011 09:06:45 PM EDT
logfile /var/svc/log/application-jenkins:default.log
restarter svc:/system/svc/restarter:default
contract_id 7207
{% endhighlight %}

If you need to debug something you can have a look at the log file for your
jenkins service at `/var/svc/log/application-jenkins:default.log`.

#### Bonus: Running Jenkins Behind Apache using Reverse Proxy

I already have a web service running on port 80, and I wanted to be able to
access Jenkins through that port. To do this I added a reverse proxy in Apache.
If you have any access controls in your apache configuration then its important
that you set the host address to <IP_ADDRESS> so that someone can’t go around your
proxy and hit Jenkins directly. Add the following to your httpd.conf to be able
to access Jenkins.

{% highlight apache %}
# Reverse proxy to Jenkins:
ProxyPass /jenkins http://localhost:7777/jenkins
ProxyPassReverse /jenkins http://localhost:7777/jenkins

# Allow access to this proxy to everyone:
<Proxy http://localhost:7777/jenkins*>
    Order deny,allow
    Allow from all
</Proxy>
{% endhighlight %}

branch_name: refs/heads/staging


text:
# ATN Client
### atn-node-js
English | [简体中文](README.md)
   ***Atn-node-js*** is a library based on **Node** and **Web3**, and is also part of the **ATN Client**. As a key component of **ATN** ecosystem, **ATN Client** connects **DBot developer** and **Application Developer**, and the following figure shows the relations .

![atn-ecosystem](http://p5vswdxl9.bkt.clouddn.com/ATN%20ecosystem.png "ATN ecosystem")

---

### ATN Client

So far, **ATN Client** has Node version and TypeScript version：
   - [atn-node-js](https://github.com/ATNIO/atn-node-js): this is node version lib ;
   - [atn-js](https://github.com/ATNIO/atn-js)：used in browser ，we can use with the sign method in [atn-wallet](https://github.com/ATNIO/atn-wallet)
   - [pyatn-client](https://github.com/ATNIO/pyatn-client): python version, easy to use.

 In the future ,we will provide main programming language like **Java**,**Python** and so on .

#### Simple usage：
-  initConfig(privateKeyFile, dbotAddress): to initialize the Channel of a DBot AI service .
-  callDBotAI(dbotAddress, uri, method, option): to call the AI service from a DBot

#### Detail usage：
-  createChannel(receiverAddress, deposit): to create AI calling channel
-  getChannelDetail(receiverAddress): get information of AI channel
-  topUpChannel(receiverAddress, value): top-up to the channel, to increase the number of callings
-  closeChannel(receiverAddress, balance, closeSignature): close the DBot AI channel
-  callDBotAI(dbotAddress, uri, method, option): call DBot AI service

### Quick start
   We prepare a simple example `ATN Client Example`([Project Address](https://github.com/ATNIO/atn-client-example)), to demonstrate how to use **atn-node-js** in the development .

#### 1. Search for a **DBot AI** service in the `AI Market`
   🔗AI Market:[link](https://market-test.atnio.net)
   For instance,: Baidu NLP API
   ```javascript
   dbotAddress = "0xe4640e4005903e147ebb54dd9ddf17e85ce53303"
   ```
   ```javascript
   uri = '/lexer'
   ```
   ```javascript
   method = "post"
   ```
   ![AI Market](http://p5vswdxl9.bkt.clouddn.com/AI_market_ui.png "AI Market UI")

#### 2. Use `atn-node-js`
   Before using this library, make sure you have successfully installed the node (version 8.0 or later).
   ```
   $ node --version
   ```
   Then Install the atn-node-js at the root directory of the JS project
   ```markdown
   $ npm install atn-node-js --save
   ```
#### 3. Development Example

The following example is in [ATN Client Example](https://github.com/ATNIO/atn-client-example) project

 * 3.1 Simple Usage

   STEP 1：Initialize the DBot Server AI service
   ```javascript
   // Code Snippets
   // 1. Import atn-node-js lib
   var Atn = require('atn-node-js');
   var key = require('../atnconfig/user1');
   const atn = new Atn(key.key);

   const dbotAddress = "0xe4640e4005903e147ebb54dd9ddf17e85ce53303"
   var privateKeyFile = "/libs/atnconfig/user.json";//you can define your own filename  and filepath

   // 2. Init the condition before calling DBot Server AI
   const result = await atn.initConfig(privateKeyFile, dbotAddress);

   ```
   ***Notice***：If you have private key ,you can use this method like this:
   ```javascript
   var privateKey = '0x01adc971225be058c7031b536375b79115ed58993c86a4ec4288f36fc9eb51b7';
   const result = await atn.initConfig(privateKeyFile, dbotAddress,privateKey);
   ```

   STEP 2：Call the DbotServer
   ```javascript

   var option = {
        headers: {
            "Content-Type": "application/json;charset=UTF-8"
          },
          responseEncoding: "GBK",
          method: "post",
          data: { text: "Baidu is a high-tech company" }
      };
      var uri = '/lexer';
      var method = 'post';
      // 3. Call DBotServer AI Service
      const result = await atn.callDBotAI(dbotAddress,uri,method,option);
   ```

 * 3.2 Detail Usage

   STEP 1：Import the **atn-node-js** lib ，and plugin your own private key in your project

   ```js
   //  Import the atn-node-js lib
   var Atn = require('atn-node-js');
   //  Config your  private key json file
   var key = require('../atnconfig/user1');
   //  create atn Object
   const atn = new Atn(key.key);
   //  set the DBot Address
   const dbotAddress = "0xe4640e4005903e147ebb54dd9ddf17e85ce53303";
   ```

   STEP 2：Create a channel to call DBot Server AI service

   ```js
   // Code Snippets :
   // 1. Import the atn-node-js lib
   ...

   const deposit = 3e18  // you can define the variable by yourself
   // 2. Use the DBotServer address which queried on AI Market
   const result = await atn.createChannel(dbotAddress, deposit)
   ```

   STEP 3：Get the channel from **DBotServer**

   ```js
   // Code Snippets :
   // 1. Import the atn-node-js lib
   ...

   // 2. Get channel infomation from DBotServer
   const result = await atn.getChannelDetail(dbotAddress);
   ```

   STEP 4：Call the DBotServer AI Service

   ```js
   // Code Snippets :
   // 1. Import the atn-node-js lib
   ...
   // Call DBotServer AI Service
   // 2. The request params config like Baidu NLP
   var option = {
     headers: {
         "Content-Type": "application/json;charset=UTF-8"
       },
       responseEncoding: "GBK",
       method: "post",
       data: { text: "Baidu is a high-tech company" }
   };
   var uri = '/lexer';
   var method = 'post';
   // 3. Call DBotServer AI Service
   const result = await atn.callDBotAI(dbotAddress,uri,method,option);

   ```

   STEP 5：Top-up into the channel

   ```js
   // Code Snippets
   // 1. Import the atn-node-js lib
   ...

   var vaule = 10e18 ; //you can define the value by yourself

   // 2. increate the usage times of DBotServer AI services
   const result = await  atn.topUpChannel(dbotAddress,vaule);

   ```

   STEP 6：Close the channel

   ```js
   // Code Snippets
   // 1. Import the atn-node-js lib
   ...

   const dbotAddress = "0xe4640e4005903e147ebb54dd9ddf17e85ce53303";
   var vaule = 10e18 ; //you can define the value by yourself

   // 2. Close the channel
   const result = await atn.closeChannel(dbotAddress,balance);
   ```

### API Document
* [atn-node-js](https://atnio.github.io/atn-node-js/0.1.37/index.html)

### Reference
* [mochajs](https://mochajs.org/#more-information)

repository: ATNIO/atn-node-js

gha_language: JavaScript

repo_name: ATNIO/atn-node-js


text:
---
layout: page
title: OpenLink Annotating Transformers
permalink: /openlink-annotators/
---

## Synchronous Annotating Transformer

### Getting a description of the transformer

As per the transformer specification a GET request will return an RDF description of the transformer.

    curl -i "http://fusepool.openlinksw.com/enr/dbpedia-spotlight-meta-fusepool"

### Transforming data

The following examples uses the following text file which you should download to the folder in which you're executing the cURL commands:

- [test.txt](/openlink/test.txt)

The following cURL invocation will post the data

    curl -i -H "Content-Type: text/plain" -H "Accept: text/turtle; q=1.0, application/rdf+xml; q=0.9, application/ld+json; q=0.8" -H "Content-Location: http://fusepool.openlinksw.com/entity" --data-binary @test.txt -X POST "http://fusepool.openlinksw.com/enr/dbpedia-spotlight-meta-fusepool"

Note 1: Use of 'Accept' and 'Content-Location' headers is optional. The fall-backs are 'text/turtle' and 'http://fusepool.openlinksw.com/entity'.

Note 2: Even if the call is to a synchronous Transformer, it may internally decide that the time to process is large and start the transformation in an asynchronous mode. This means that you will need an additional GET request to get the transformation result like in the followng section.

## Asynchronous Annotating Transformer

The transformer `http://fusepool.openlinksw.com/enr-async/dbpedia-spotlight-meta-fusepool` alway handles requests asynchronously and can thus be used to try out the asynchronous transformation mode.

### Getting a description of the transformer

No difference here....

    curl -i "http://fusepool.openlinksw.com/enr-async/dbpedia-spotlight-meta-fusepool"

### Transforming data

The transformation of the data requires two steps, POSTing the data and GETting the result:

#### POSTing the data

    curl -i -H "Content-Type: text/plain" -H "Accept: text/turtle; q=1.0, application/rdf+xml; q=0.9, application/ld+json; q=0.8" -H "Content-Location: http://fusepool.openlinksw.com/entity" --data-binary @test.txt -X POST "http://fusepool.openlinksw.com/enr-async/dbpedia-spotlight-meta-fusepool"

The answer to the request will look similar to this:

    HTTP/1.1 202 Accepted
    Server: Virtuoso/07.10.3211 (Linux) x86_64-redhat-linux-gnu  VDB
    Connection: Keep-Alive
    Content-Type: text/html; charset=UTF-8
    Date: Wed, 05 Nov 2014 13:27:57 GMT
    Accept-Ranges: bytes
    Location: /enr-async/status/30
    Content-Length: 0

Note: Use of 'Accept' and 'Content-Location' headers is optional. The fall-backs are 'text/turtle' and 'http://fusepool.openlinksw.com/entity'.

#### GETting the result

The results can be retrieved at the location indicated by the Location-Header in the response to the POST request.

    curl -i "http://fusepool.openlinksw.com/enr-async/status/30"


text:
---
layout: sidebar
sidebar_align: right
title: Where Is the Clinic
permalink: /where-are-the-clinics.html
---
** I have recently moved to Pembrokeshire and am practising in Goodwick near Fishguard. If you have seen me in Cardiff and are needing more treatment, please do get in touch, I love hearing from my past patients, and I will be very happy to recommend some good people in Cardiff who can help you.**

**My main clinic day is currently Wednesday, as the practise grows I will add more days.At the moment, depending on the availability of clinic space, I am able to be fairly flexible.**

### Ivybridge Spa
<address>
Ivy Bridge Cottages

Goodwick

SA64 0JT

Google Maps Link: [https://g.page/theivybridgespa-co-uk](https://g.page/theivybridgespa-co-uk)

</address>

### Directions
#### From Haverfordwest:

Follow the A40 towards Fishguard.
Turn left at the roundabout before entering Fishguard onto the by-pass following signs for the Ferry terminal.
Turn left at the roundabout at the bottom of the by-pass following the sea front towards the Ferry terminal.
At the next roundabout turn left again and follow the A487 towards St Davids for approximately 1 mile until you reach the signs for Ivybridge on your left.

#### From Cardigan:

Follow the A487 from Cardigan into Fishguard via the small picturesque harbor at Lower Town.
Turn right at the roundabout at the center of Fishguard (Second Exit).
Follow the road through Fishguard and into Goodwick (turning right again at the Fishguard by-pass roundabout).
At the next roundabout turn left and follow the A487 towards St Davids for approximately a mile until you reach the signs for Ivybridge on your left.

#### From St Davids:

Follow the A487 from St Davids until you reach Goodwick.
The Ivybridge is on your right after entering the 30mph speed limit.


text:
import BlogPost from '../../components/blog-post/blog-post.component';

export const meta = {
published: true,
publishedAt: '2020-03-11',
readingTime: 7,
url: '/blog/4-important-skills-software-devs',
title: '4 Most Important Skills for Software Developers',
summary: 'What are the most important skills needed by software developers to be successful? Find out in this post.',
src: '/blog-images/4-important-skills-software-devs/soft-skills_w_683.jpg',
srcSet: '/blog-images/4-important-skills-software-devs/soft-skills_w_200.jpg 200w, /blog-images/4-important-skills-software-devs/soft-skills_w_522.jpg 522w, /blog-images/4-important-skills-software-devs/soft-skills_w_683.jpg 683w',
alt: 'software developer skills',
sizes: '',
imgAuthorAttribution: 'Coreaxis',
imgAttributionUrl: 'https://coreaxis.com/why-soft-skills-training-is-still-trending-in-2019/'
};

export default ({ children }) => <BlogPost meta={meta}>{children}</BlogPost>;

Last Sunday I was teaching English at my local English club and the theme that we had for the session was about job skills. What are the skills that we need today in order to be successful at our jobs?

We all mentioned the skills we think are important and needed for jobs, but at the end we all agreed that skills needed for one particular job are different from another job. For example, while an accountant needs to have great number crunching abilities, a translator/interpreter needs to have excellent language skills. But there are also certain skills that are important for every job, like being able to work with others.

So what are the most important skills needed by software developers to be successful in their field? Here are the top 4 skills I think are of most important.

**1. Problem solving**

Software developers are problem solvers. Nearly all tasks assigned to developers require finding a solution to a problem. Good software developers know how to define problems well, break them down into smaller problems, and find an optimal solution using the resources available. They have a systematic method of approaching a problem. Actually there is no code to write if you don’t even know what to write.

Problem solving is a skill that can be learned and improved. After learning a programming language, it is good to learn about Data Structures and Algorithms using that programming language. It would really beneficial to know basic data structures like arrays, linked lists, trees, and graphs, and common algorithms like binary search, DFS, BFS and sorting algorithms. Although you may not always use them in your day-to-day tasks, knowing data structures and algorithms will help you solve problems differently from those who don’t know them.

There are plenty of resources to learn DS and Algorithms online. I usually use Udemy to learn with videos, but you can also find many other resources on the internet. I mainly code in JavaScript, and here are some of the best courses on Udemy about DS and Algorithms using JavaScript:

-   [Master the Coding Interview Data Structures And Algorithms by Andrei Neagoie](https://www.udemy.com/course/master-the-coding-interview-data-structures-algorithms/)
-   [JS Algoritms and Data Structures Masterclass by Colt Steele](https://www.udemy.com/course/js-algorithms-and-data-structures-masterclass/)

There are many online platforms, like HackerRank, LeetCode, and CodeSignal, where you can practice and improve your problem solving skills.

**2.  They have to report to managers and supervisors, attend meetings, talk to clients, and also ask help from other developers. It is therefore crucial to communicate effectively in order to avoid misunderstandings.

There is a saying that a **problem well stated is half solved**. You will not know everything, and at some point you will have to ask for help from people who are better than you. If you are able to clearly express yourself, they will easily be able to help you.

When you have great speaking skills, you may be called to speak at developer meetups and conferences

Written communication skills are also important. Writing documentation is part of the software development. As a software developer, you may be required to write documentation for an API or user manual for users of the software. The documentation must be clear and easy to understand.

**3. Working with others**

When I was still in school, I used to work on software projects alone. They were small in scope, so working alone wasn’t a problem at all. In the corporate world, however, software projects are done in teams. You have to collaborate with designers, frontend developers, backend developers, managers, product owners and other stakeholders of the projects. Everyone has a certain role in the success of the project. If you have an attitude and you only want to do things your own way, you are going to put the project at risk.

Creating software is supposed to be a team effort. It is like playing football. You have to play as a team and not as individuals. Even if you have the best player in the team, you will not win any match if the players of the team don’t work together.

**So learn how to work with others.**

**4. Ability to learn new things**

The software world is moving extremely fast -- new frameworks, tools, platforms, programming languages . You will be left behind if you don’t know how to learn new things. On the other hand, if you are willing and able to adapt to the changing software development market and technologies, you will have significant advantage over others who aren’t willing to adapt to change. You will also always be in demand, and you will get more opportunities come to you.

However, I would also like to say that you have to learn the right things. You cannot learn every new shiny technology that comes out every month. There is simply no time for that and it will kill your productivity. Instead, try to focus your learning on the tech stack you are using. For example, if you are a JavaScript developer, learn stuff related to the JavaScript stack (frontend stuff such as HTML, CSS, JavaScript frameworks, and JavaScript in backend such as Node.js).

## Conclusion

These are the top 4 skills I think are important for software developers to be able to progress in their career.

1. Problem Solving
2. Communication Skills
3. Working with others
4. Ability to learn new things

All these skill can be learned and developed. Do you already have these skills? Are there other skills that need to be added in the list?

repository: nainarazz/portfolio-website

repo_name: nainarazz/portfolio-website


text:
---
layout: post
title: "Build a shopping cart with Spring Web Flow 2, part 3"
date: 2008-05-07 17:51:39
comments: true
categories: [Chapter 05 - Web Flow, Tutorials]
---

This post is part of a three-part series: Part 1 | Part 2 | Part 3

Building out the application

Now that we've gotten Spring MVC and SWF working, it's time to build out the shopping cart application.  Please download the following file before continuing:

mycart3.zip

We won't be looking at every aspect of this application, but I'll highlight the most interesting pieces from a SWF point of view.

Dependencies for mycart3.zip

Besides the dependencies we had for mycart2.zip, there are four others you'll need:

cglib-nodep-2.1_3.jar

jstl.jar

standard.jar

sitemesh-2.3.jar (from www.opensymphony.com/sitemesh/download.action)

After you download mycart3.zip (and its dependencies), you can deploy it and then point your browser at

http://localhost:8080/mycart/home.do

Here are some notes to keep in mind:

My registration and login flows don't actually "do" anything. They're not hooked up to Spring Security and they're not hooked up to a database.  So when you register you can just hit the submit button,and when you log in you can just hit the login button.  I just wanted to focus on the flows themselves.

I'm using Sitemesh to ensure a unified layout across the pages. Even if you are not familiar with Sitemesh, don't worry: it is very straightforward.  Basically you just put a servlet filter in front of the pages and the filter decorates the pages with a template (/WEB-INF/jsp/pagetemplate.jsp in this case) according to a simple configuration file (/WEB-INF/decorators.xml). If however you don't want to use Sitemesh, simply remove the filter from web.xml and Sitemesh is gone.

Multiple flows

Any given app may contain multiple flows, and mycart3 is such an app.  We have four different flows:

addToCart: add an item to a shopping cart

checkout: shopping cart checkout process

login: log into the app

register: register for a new user account

In some of the cases we have what we would intuitively consider a flow in that there are multiple states involved; in other cases there is only one state to speak of and so it may seem strange to regard the flow as being a flow.  However we'll see how that can make sense in the following section.

To create multiple flows, you will need to do the following. First, create the flow definition files and put them in your /WEB-INF/flows directory (or wherever you decided to put them).  Then add the flow locations to the flow registry, and the flow URL mappings to your SimpleUrlHandlerMapping (if that's what you're using), in your Spring application context, like so:

Code listing: /WEB-INF/mycart-servlet.xml

...

<bean id="flowUrlMappings" class=
        "org.springframework.web.servlet.handler.SimpleUrlHandlerMapping">
    <property name="mappings">
        <value>
            /addToCart.do=flowController
            /checkout.do=flowController
            /account/login.do=flowController
            /account/register.do=flowController
        </value>
    </property>
    <property name="alwaysUseFullPath" value="true"/>
</bean>

<flow:flow-registry id="flowRegistry" flow-builder-services="flowBuilderServices">
    <flow:flow-location path="/WEB-INF/flows/addToCart.xml"/>
    <flow:flow-location path="/WEB-INF/flows/checkout.xml"/>
    <flow:flow-location path="/WEB-INF/flows/login.xml"/>
    <flow:flow-location path="/WEB-INF/flows/register.xml"/>
</flow:flow-registry>

...

Once you have those in place you should be set up for multiple flows.  Point your links at them and try them out!

Subflows

Going hand-in-hand with the idea of multiple flows is the idea that some flows might be subflows of other flows.  In mycart3,all four flows can be independently accessed, but in addition to that we have the addToCart, login and register flows being subflows to the checkout flow.  See Figure 3.

Figure 3. Subflows.

Here's the idea.  The three flows we've identified as subflows are defined as separate flows because clearly there are use cases where it makes sense for them to be accessed outside of a checkout process. For example, we want to be able to add products to a shopping cart while we're browsing the product catalog.  And of course we want people to be able to register and login even if they're not in a checkout process.

But those are also flows that we might want to include as part of a checkout process too.  During checkout, we might want to recommend products to the customer.  Or if the user hasn't yet logged in or registered, we'd want them to do that as part of the checkout process rather than forcing them to do that before they could enter the checkout process.

By defining the login, registration and add-to-cart as flows, we make them available both independently (as top-level flows) and also as part of a larger flow (like the checkout flow).  That's why we have these defined as flows even though they are currently implemented as single-state flows.  (It is however easy to imagine these being multi-state flows.  For example, the login flow may ask you to answer a challenge question if it detects that you're coming in from an unusual IP address, or the add-to-cart flow may ask you to enter a quantity before proceeding.)

So here is the checkout flow:

Code listing: /WEB-INF/flows/checkout.xml

<?xml version="1.0" encoding="UTF-8"?>
<flow xmlns="http://www.springframework.org/schema/webflow"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://www.springframework.org/schema/webflow
        http://www.springframework.org/schema/webflow/spring-webflow-2.0.xsd">

    <!-- Get the products one time, at the beginning of the flow -->
    <on-start>
        <set name="flowScope.products" value="cartService.products"/>
        <set name="flowScope.shippingOptions" value="cartService.shippingOptions"/>
    </on-start>

    <!-- If not specified, the start state is the first state specified. -->
    <view-state id="viewCart" view="viewcart">
        <!-- cart is available to SWF but not stored on the session under that
             name when using AOP proxy -->
        <on-render>
            <!-- Carry cart from Spring app context to request scope -->
            <set name="requestScope.shoppingCart" value="shoppingCart"/>
            <set name="requestScope.recommendations" value="cartService.recommendations"/>
        </on-render>
        <transition on="addToCart" to="addProductToCart"/>
        <transition on="register" to="register"/>
        <transition on="login" to="login"/>
    </view-state>

    <subflow-state id="addProductToCart" subflow="addToCart">
        <!-- This is where we go when the subflow returns. productAdded is
             the name of an end-state. -->
        <transition on="productAdded" to="viewCart"/>
    </subflow-state>

    <!-- New customers create a new account before moving forward -->
    <subflow-state id="register" subflow="register">
        <transition on="accountAdded" to="paymentAndShipmentOptions"/>
        <transition on="cancelRegistration" to="viewCart"/>
    </subflow-state>

    <!-- Existing customers log in before moving forward -->
    <subflow-state id="login" subflow="login">
        &lt!-- This is where we go when the subflow returns. productAdded is
             the name of an end-state. -->
        <transition on="loginOk" to="paymentAndShipmentOptions"/>
    </subflow-state>

    <!-- Payment and shipment options -->
    <view-state id="paymentAndShipmentOptions" view="options">
        <transition on="submit" to="confirmOrder"/>
        <transition on="back" to="viewCart"/>
    </view-state>

    <!-- Confirm order -->
    <view-state id="confirmOrder" view="confirmorder">
        <on-render>
            <set name="requestScope.shoppingCart" value="shoppingCart"/>
        </on-render>
        <transition on="continue" to="thankYou">
            <evaluate expression="cartService.submitOrderForPayment()"/>
        </transition>
    </view-state>

    <!-- Thank you page -->
    <view-state id="thankYou" view="thanks">
        <transition on="continue" to="shop"/>
    </view-state>

    <!-- Exit the flow, letting the user return to shopping -->
    <end-state id="shop" view="externalRedirect:contextRelative:/home.do"/>

    <global-transitions>
        <transition on="cancelCheckout" to="shop"/>
    </global-transitions>
</flow>

In the code above, we are using the <subflow-state> element to call a subflow from a parent flow.  The subflow attribute specifies one of the flows you registered with the flow registry in the Spring configuration.  The flow starts at the subflow's start state, and continues until the subflow hits an end state.  The end state IDs provide keys that you can reference from the calling flow to effect state transitions.  For example, in the flow above,accountAdded is one of the end states for the register flows, and so one of the <transition> elements references that end state.

Recall from register.xml (see page 4) that the end states specified a view attribute.  If the register flow is called directly, then SWF will use the view attribute to decide which view to show the user when the flow reaches a given end state.  If, however, the flow is called as part of a subflow (instead of being called directly), SWF will ignore the view attribute and instead follow whatever transition is defined in the calling <subflow-state>.

Using EL to call services

SWF allows you to make calls against service beans using an expression language (EL).  You can use either Unified EL or else OGNL for that, as mentioned earlier in the article.  We happen to be using OGNL though I understand that Unified EL and OGNL are mostly the same,at least where their core syntax is concerned.

There are various places in your flow where you might want to invoke service beans, and SWF provides various mechanisms for doing that.  Here's a table showing how to call services from different locations in your flow definition file:

                Location
                How to call the service bean

                On flow start
                /flow/on-start element

                On state entry
                /flow/view-state/on-entry element

                Immediately before rendering a view
                /flow/view-state/on-render element

                On state exit
                /flow/view-state/on-exit element

                On state transition
                /flow/view-state/transition/evaluate element

                On flow end
                /flow/on-end element

Table 2. How to call service beans from different locations.

Note that the above does not represent a 100% complete list of places where you can use EL, but it gives you most of the major cases and also the basic idea.

In checkout.xml we've used a number of the methods above.  For example, we use <on-start> to grab the product catalog and shipping options from the cart service and place them on the flow scope, which allows them to be used for the duration of the flow.  The value attribute on the set element is specified using EL.  (It looks a lot like JSP EL, if you are familiar with that.)  The cartService bean is available because we defined a Spring bean with that ID.

We also use <on-render> to prepare the viewCart state for rendering.  In this case, we place the user's shopping cart on the request scope so the JSP can easily reference it, and we also pull some recommendations off of the cart service and place those on the request scope as well.  Once again the value attribute is specified using EL.

Global transitions

At the end of checkout.xml, you will see that I've defined a <global-transitions> element.  This allows me to define a transition that applies to all states in the flow.  In this case, any time the user raises the cancelCheckout event, the global transition I've defined will kick in and carry the user to the shop state. Pretty handy for transitions that occur in multiple places throughout the flow.

That's our whirlwind tour

That concludes this tutorial on Spring Web Flow 2.0.  We've really only scratched the surface—for instance, we haven't even touched the new AJAX support that SWF 2.0 introduces—but this should give you an overall feel for how things work.  The SWF 2.0 distribution comes with a hotel booking sample application that shows you how to get SWF working with form validation and persistence as well (areas I've suppressed in this article so that I could focus on flow definition).

If you have suggestions and especially corrections to the article or the code, please leave them below.  SWF 2.0 is new so I have no doubt that you will be able to show me places where I could be doing something better.  Thanks!

Resources

A Maven version of the download is available. The target link is in Spanish but there's a zip file at the bottom called WebFlowExample.zip that you can download. If you want to read the target link in English, you can use Alta Vista's free Babel Fish translation service.

This post is part of a three-part series: Part 1 | Part 2 | Part 3

Post migrated from my Wheeler Software site.

repository: springinpractice/sip-blog

extension: markdown

repo_name: springinpractice/sip-blog


text:
# Readme generator

  ![Github MIT license](https://img.shields.io/badge/license-MIT-darkred)

   ![Javascript badge](https://img.shields.io/badge/Made%20with-JavaScript-1f425f.svg)
  ## Description
  This project uses javascript, node.js, and inquirer to efficiently generate a professional grade readme.

  [Link to Demo](https://drive.google.com/file/d/1cpqH26eTFVUUy79PV7ieTkZsBCKlRQRY/view?usp=sharing)
  ![Screen Shot of Questions](https://user-images.githubusercontent.com/88289885/135550412-b14a22d2-ea78-4f59-99ab-c2e735f80e03.png)

  ## Table of Contents
  * [Installation](#installation)
  * [Usage](#usage)
  * [License](#license)
  * [Contributing](#contributing)
  * [Tests](#tests)
  * [Questions](#questions)

  ## Installation
  This needs both node.js and inquirer. First, open the terminal and type npm init, hit enter, and then type npm install inquirer. This should create the json, node modules, and install inquirer.
  ## Usage
  This app creates professional-grade readmes efficiently
  ## License
  This project is license under MIT
  ## Contributing
  none
  ## Tests
  npm test
  ## Questions
  If you have any questions about this project, you may contact me directly at<EMAIL_ADDRESS>You can also take a look at more of my projects at https://github.com/Kbentley8.

branch_name: refs/heads/main


text:
---
layout:   page
title:    LaTeX Course Index
subtitle: Template for writing a condensed course index leveraging LaTeX indexing
---

[**See examples for SANS courses here !**](https://github.com/dhondta/tex-course-index-template/tree/master/examples)

##  Introduction

The goal of this template is to provide a way to write very condensed indexes typically for courses with multiple books. It leverages [LaTeX indexing](https://en.wikibooks.org/wiki/LaTeX/Indexing) by using a `.idx` file for organizing the index entries. The way this template can be used is by directly editing the `.idx` file.

> See folder [`examples`](examples/) for some real-life indexes which have already desmontrated their effectiveness.

Here is an example preview:

Preview image generated with this tool

##  Structure

The template is structured in the following way:

- [`main.tex`](https://github.com/dhondta/tex-course-index-template/blob/master/src/main.tex): This is the main TeX file to be compiled. No need to edit this file unless you require to adapt the layout of the course index.
- [`main.idx`](https://github.com/dhondta/tex-course-index-template/blob/master/src/main.idx): This holds the index entries of the books of the course to be indexed.
- [`data.tex`](https://github.com/dhondta/tex-course-index-template/blob/master/src/data.tex): This defines a few course-related variables (title, code, date and version) to be used in [`main.tex`](https://github.com/dhondta/tex-course-index-template/blob/master/src/main.tex).
- [`lib`](https://github.com/dhondta/tex-course-index-template/blob/master/src/lib): This folder contains the images called in [`main.tex`](https://github.com/dhondta/tex-course-index-template/blob/master/src/main.tex) and for use in [`main.idx`](https://github.com/dhondta/tex-course-index-template/blob/master/src/main.idx) (useful e.g. for mentioning that a tool is only for linux ; then use the `\linux` command in the `\indexentry`).

##  Compilation

The compilation can easilly be configured in [Texmaker](https://en.wikipedia.org/wiki/Texmaker) by defining a *Quick Build Command*:

1. Go to the menu *Options*
2. Select *Configure Texmaker*
3. Go to tab *Quick Build*
4. In the field *User : (...)*, replace the command with:

       makeindex %.idx -s lib/std.ist|pdflatex -synctex=1 -interaction=nonstopmode %.tex|evince %.pdf|cp %.idx %.idx.bak|rm %.ilg %.ind %.aux %.synctex.gz

5. Then click *OK*

When editing the index with [Texmaker](https://en.wikipedia.org/wiki/Texmaker):

1. Open [`main.tex`](https://github.com/dhondta/tex-course-index-template/blob/master/src/main.tex)
2. Go to the menu *Options*
3. Select *Define Current Document as "Master Document"*
4. Open [`main.idx`](https://github.com/dhondta/tex-course-index-template/blob/master/src/main.idx) for edition
5. Click on *Quick Build* to compile

This will produce [`main.pdf`](https://github.com/dhondta/tex-course-index-template/blob/master/src/main.pdf) with all the index entries organized in a two-columns document.

NB: Do not forget to edit [`data.tex`](https://github.com/dhondta/tex-course-index-template/blob/master/src/data.tex).

> **Important**: It could happen that Texmaker is configured to remove temporary files while exiting, including `main.idx`. That's why the *Quick Build* herebefore includes `cp %.idx %.idx.bak` to backup this file and not to loose hours of work adding index entries. If removal still occurred, simply restore `main.idx.bak` to `main.idx`. Note that, consequently, the **backup is not made if you do not build the document**. So, **mind clicking regularly on the *Quick Build* button** !

##  Making your index

The only files to be edited when making a new index are:

1. [`data.tex`](https://github.com/dhondta/tex-course-index-template/blob/master/src/data.tex): Define the course attributes there (title, code, date, version).
2. [`main.idx`](https://github.com/dhondta/tex-course-index-template/blob/master/src/main.idx): Define the index entries there.

### `idx` File Structure

[`main.idx`](https://github.com/dhondta/tex-course-index-template/blob/master/src/main.idx) file comes organized with a few example sections. Basically, one section represents a symbol, a digit or a letter for sorting the references. In this template:
- Symbols are reserved for the *Topics* section (e.g. for providing the course structure)
- Digits are reserved for the *Categories* section (e.g. for sorting interesting resources such as tools, commands, standards, ...)
- Letters are used normally

The *Topics* and *Categories* titles are defined in [`lib/std.ist`](https://github.com/dhondta/tex-course-index-template/blob/master/src/lib/std.ist).

### LaTeX Indexing Basics

The raw material of an `idx` file is the `indexentry`. The signature of this command is the following:

    \indexentry{some_text}{page_number_or_range}

> Example of valid index entry: `\indexentry{\textbf{Course Philosophy}}{1-10}`

It is possible to provide a reference and to alias it with a desired text thanks to the "`@`" symbol:

    \indexentry{reference@some_text}{page_number_or_range}

> **Important note**: The format of `reference` affects the index reference location. That is, an alias consisting of:
>
> - 1+ digits and 1+ letters: will be sorted as a symbol, thus in the *Topics* section.
> - only digits: will be sorted as a number, thus in the *Categories* section.
> - 1+ letters then anything else: will be sorted as text, thus in the letter sections.

It is also possible to indent a reference under another one thanks to the "`!`" symbol:

    \indexentry{some_text!some_indented_text}{page_number_or_range}

> Example of valid index entry: `\indexentry{\textbf{Course Philosophy}!Principle 1}{10}`

One can format the page number by using the "`|`" symbol:

    \indexentry{some_text!some_indented_text|command}{page_number_or_range}

> Example of valid index entry: `\indexentry{\textbf{Course Philosophy}|textbf}{10}`

### Commands Available in the Template

`main.tex` defines a few useful commands that can be mixed with `indexentry` in `main.idx`. Note that, in the following descriptions, `...` must each time be set so that the entry is sorted at the right location in the document.

- Adding a blank line: `\blankline`

      \indexentry{...@\blankline|comment}{0}

  > Example: `\indexentry{1b@\blankline|comment}{0}`

- Insert a page break: `\newpage` (standard in LaTeX)

      \indexentry{...@\blankline|newpage \comment}{0}

  > Example: `\indexentry{999@\blankline|newpage \comment}{0}`

- Fill in the page number with the book code: `\book{x}`

      \indexentry{...|book{x}}{...}

  > Example: `\indexentry{A reference in the third book|book{3}}{123}`

- Insert a rating with stars: `\rate{x}`

      \indexentry{... \rate{x}|...}{...}

  > Example: `\indexentry{A very useful reference \rate{5}|book{1}}{45}`

- Insert graphics: `\linux`, `\mac`, `\win`, `\all`, ...

      \indexentry{... \[graphic]|...}{...}

  > Example: `\indexentry{A Windows-related reference \win|book{2}}{67}`

### Predefined Icons

For convenience, multiple shorcuts are predefined in [`main.tex`](https://github.com/dhondta/tex-course-index-template/blob/master/src/main.tex) and the [`lib`](https://github.com/dhondta/tex-course-index-template/blob/master/src/lib) folder for displaying icons:

- `\all`: cross-platform ; Linux, Windows and Mac
- `\android`: Android
- `\cloud`: cloud icon with a server
- `\coin`: dollar (for paid asset)
- `\ios`: iOS
- `\linux`: Linux
- `\mac`: Mac OS
- `\note`: paper note with a pen
- `\portable`: USB key
- `\python`: Python script
- `\script`: general-purpose script
- `\question`: red question mark (e.g. for pointing an entry related to an exam question)
- `\solaris`: Soralis
- `\web`: Web-related asset
- `\win`: Windows

##  Related Projects

You may also like these:

- [TeX Book Template](https://github.com/dhondta/tex-book-template): A template for writing a nice book with LaTeX.
- [TeX Cheat Sheet Template](https://github.com/dhondta/tex-cheat-sheet-template): A template for creating a nice cheat sheet with LaTeX.
- [TeX Master Thesis Template](https://github.com/dhondta/tex-master-thesis-template): A template for writing a nice master thesis dissertation with LaTeX.
- [TeX Poster Template](https://github.com/dhondta/tex-poster-template): A template for creating a nice scientific poster with LaTeX.


text:
# CanCan

[![Build Status](https://github.com/dfinity/cancan/workflows/CI/badge.svg)](https://github.com/dfinity/cancan/actions)

> A scalable video-sharing service.

## Installation

### Prerequisites

- [Internet Computer SDK](https://sdk.dfinity.org)
- [Node.js](https://nodejs.org)
- [Python](https://www.python.org)
- [Vessel@0.6.0](https://github.com/dfinity/vessel/releases/tag/v0.6.0)

If you don't have vessel yet you can install it by running an install script included in the project:

```shell
$ ./scripts/vessel-install.sh
```
MacOS might ask if you're sure you trust this package. You can safely accept

Double-check you have [vessel](https://github.com/dfinity/vessel) installed at version 0.6.*, then clone this repository and navigate to the `cancan` directory.

```shell
$ vessel --version
# vessel 0.6.0

$ git clone git@github.com:dfinity/cancan.git
$ cd cancan
```

Start a local Internet Computer replica.

```shell
$ dfx start
```

Execute the following commands in another terminal tab in the same directory.

```shell
$ npm ci # <- This installs packages from the lockfile for consistency

$ ./bootstrap.sh
```

This will deploy a local canister called `cancan_ui`. To open the front-end, get the asset canister id by running `dfx canister id cancan_ui`. Then open your browser, and navigate to `http://<cancan_ui-canister-id>.localhost:8000/sign-in`.

## Frontend Development

To run a development server with fast refreshing and hot-reloading, you can use this command in the app's root directory:

```shell
$ npm run start
```

Your default browser will open (or focus) a tab at `localhost:3000`, to which you must then append `/?canisterId=${cancan_ui_canister_id}`, where `cancan_ui_canister_id` is typically (at current) `ryjl3-tyaaa-aaaaa-aaaba-cai`.

Now you can make changes to any frontend code and see instant updates, in many cases not even requiring a page refresh, so UI state is preserved between changes. Occasionally adding a CSS rule won't trigger an update, and the user has to manually refresh to see those changes.

## Internet Identity Locally

Clone and setup [the project](https://github.com/dfinity/internet-identity) and make sure that `internet_identity` is deployed, and you have the front-end available. That should allow you to do auth locally to try out the new Internet Identity service. For production, we will probably configure `identity.ic0.app` to be running this canister, but for now this is how to get it running.

repository: functionland/dfinity

repo_name: functionland/dfinity


text:
+++
title = "This Week In Veloren 68"
description = "0.6, Networking"

date = 2020-05-18
weight = 0
slug = "devblog-68"

[extra]
banner = "https://cdn.discordapp.com/attachments/541307708146581519/712353024118358087/P0L7gSo.png"

[taxonomies]
tags = ["devblog"]
+++

This week 0.6 was launched! We take a look at the telemetry from the launch
party. @AngelOnFira has done some network analysis on Veloren. A lot of bugs
were squashed before the 0.6 release.

\- AngelOnFira, TWiV Editor

# Contributor Work

Thanks to this week's contributors, @jbeich, @Slipped, @Silentium, @Pfau,
@xMAC94x, @imbris, @zesterer, @treeco, @Songtronix, @Shandley, @LunarEclipse,
@mockersf, @CapsizeGlimmer, @AngelOnFira, and @Acrimon!

0.6 was finally released last weekend! This update was the combination of many
contributors' efforts, and focused on adding content to Veloren. The release
party saw nearly 50 concurrent players on the server at once. It turns out that
the 0.6 release has brought more players to Veloren as well. Before the update,
there were on average 1.57 active players on the server at once, whereas now
that has increased to 3.2. The team will be meeting next weekend to have the
intro meeting for 0.7.

{{
    audio(src="https://cdn.discordapp.com/attachments/696825216868810855/712296069991497849/Leap_of_faith.ogg",
    caption="Leap of Faith by @badbbad")
}}

{{
    img(src="https://cdn.discordapp.com/attachments/597826574095613962/711698259827228742/snap2020-05-17-17-54-21.png",
    caption="Vestal Cleric Set by @AlbinoAxototl")
}}

@Redo11 has been working on adding polish translations. @LunarEclipse fixed bug that
caused crashes in the packaged versions of Veloren, and also updated the AUR for
0.6. @DaddyDemon started hosting an NA Veloren server which you can join at
`<IP_ADDRESS>`. @Silentium got their armor branch merged. Persistence saw some
quick improvements in anticipation for the launch, including saving the level of
players. @YuriMomo and the team working on WGPU found a memory leak in the
crate, and created an issue that you can check out
[here](https://github.com/gfx-rs/wgpu/issues/650).

{{
    audio(src="https://cdn.discordapp.com/attachments/712292564740341831/712293382248202271/Game_On.mp3",
    caption="Game On! by @sharpie")
}}

{{
    img(src="https://cdn.discordapp.com/attachments/467861553178345502/711209450676944989/unknown.png",
    caption="Big Boy by @Gemu")
}}

# 0.6 Release

{{ youtube(id="kjDFVgWYMd4") }}

Another few months, another Veloren release! The launch server was run on
Digital Ocean. Below you'll find lots of telemetry from the launch party. The
changelog is quite long, but this is the place for recognition of the efforts
made to Veloren, so here it is verbatim!

```
## [0.6.0] - 2020-05-16

### Added

- Added music system
- Added zoomable and rotatable minimap
- Added rotating orientation marker to main-map
- Added daily Mac builds
- Allow spawning individual pet species, not just generic body kinds
- Configurable fonts
- Configurable keybindings from the Controls menu
- Translation status tracking
- Added gamma setting
- Added new orc hairstyles
- Added SFX for wielding/unwielding weapons
- Fixed NPCs attacking the player forever after killing them
- Added SFX for collecting, dropping and using inventory items
- New attack animation
- Weapon control system
- Game pauses when in single player and pause menu
- Added authentication system (to play on the official server register on https://account.veloren.net)
- Added gamepad/controller support
- Added player feedback when attempting to pickup an item with a full inventory
- Added free look
- Added Italian translation
- Added Portuguese translation
- Added Turkish translation
- Complete rewrite of the combat system into a state machine
- Abilities like Dash and Triplestrike
- Armor can now be equipped as items
- Fireball explosions
- Inventory supports stacking
- Many new armors and weapons to find in chests
- Fleshed out "attack" animation into alpha, beta and spin type attacks
- Fleshed out range attack into charging and shooting animations for staff/bow
- Customized attack animation for hammers and axes
- Added German translation
- Added a silhouette for players when they are occluded
- Added transparency to the player when zooming in
- Made armor and hotbar slots actually function
- Added dragging and right-click to use functionality to inventory, armor & hotbar slots
- Added capes, lanterns, tabards, rings, helmets & necklaces as equippable armor
- 6 new music tracks
- Added basic world and civilization simulation
- Added overhauled towns
- Added fields, crops and scarecrows
- Added paths
- Added bridges
- Added procedural house generation
- Added lampposts
- Added NPCs that spawn in towns
- Added simple dungeons
- Added sub-voxel noise effect
- Added waypoints next to dungeons
- Made players spawn in towns
- Added non-uniform block heights
- Added `/sudo` command
- Added a Level of Detail (LoD) system for terrain sprites and entities
- Added owl, hyena, parrot, cockatrice, red dragon NPCs
- Added dungeon entrances
- Villagers tools and clothing
- Cultists clothing
- You can start the game by pressing "enter" from the character selection menu
- Added server-side character saving
- Player now starts with a lantern. Equipping/unequipping a lantern has the same effect as the `/lantern` command
- Added tab completion in chat for player names and chat commands
- Added server persistence for character stats
- Added a popup when setting your character's waypoint
- Added dungeon arenas
- Added dungeon bosses and rare boss loot
- Added 2 sets of armour. One Steel and one Leather.

### Changed

- The /give_item command can now specify the amount of items. Syntax is now `/give_item <name> [num]`
- Brighter / higher contrast main-map
- Removed highlighting of non-collectible sprites
- Fixed /give_exp ignoring player argument
- Extend run sfx to small animals to prevent sneak attacks by geese.
- Decreased clientside latency of ServerEvent mediated effects (e.g. projectiles, inventory operations, etc)
- Started changing the visual theme of the UI
- Merge of the Bag and Character-Screen
- Merge of the Map and Questlog
- Overhauled icon art
- Asset cleanup to lower client-size
- Rewrote the humanoid skeleton to be more ideal for attack animations
- Arrows can no longer hurt their owners
- Increased overall character scale
- `/sudo player /tp` is short for `/sudo player /tp me`
- The `/object` command can create any object in comp::object::Body
- The `/help` command takes an optional argument. `/help /sudo` will show you information about only the sudo command.
```

{{
  img(src="https://cdn.discordapp.com/attachments/449650240350453760/711231234533228595/unknown.png",
  caption="")
}}

{{
  img(src="https://cdn.discordapp.com/attachments/541307708146581519/712278818060238868/unknown.png",
  caption="")
}}

We almost hit 50 players for this launch party!

{{
  img(src="https://cdn.discordapp.com/attachments/541307708146581519/712278889870655558/unknown.png",
  caption="")
}}

{{
  img(src="https://cdn.discordapp.com/attachments/541307708146581519/712279233833205875/unknown.png",
  caption="")
}}

{{
  img(src="https://cdn.discordapp.com/attachments/541307708146581519/712280363862589500/unknown.png",
  caption="")
}}

{{
  img(src="https://cdn.discordapp.com/attachments/541307708146581519/712280712539275315/unknown.png",
  caption="")
}}

{{
  img(src="https://cdn.discordapp.com/attachments/541307708146581519/712281088894042132/unknown.png",
  caption="")
}}

{{
  img(src="https://cdn.discordapp.com/attachments/541307708146581519/712281641518759976/unknown.png",
  caption="")
}}

{{
  img(src="https://cdn.discordapp.com/attachments/541307708146581519/712281528167825518/unknown.png",
  caption="")
}}

Above we see persistence running on the launch party server. In the week leading
up to the launch, we started seeing many issues caused by delay in persistence.
Below you can see what the length of the delays was. This was likely caused by
the fact that normally our main server run on a unit with a hard drive, whereas
the launch party ran on a server with a solid-state drive. The times taken for
saving are still quite high, since disk input/output takes significantly longer
than accessing either RAM or the CPU Cache.

{{
  img(src="https://media.discordapp.net/attachments/541307708146581519/712282870600958002/unknown.png",
  caption="")
}}

# Network Analysis by @AngelOnFira

After playing with Wireshark during the NorthSec CTF last weekend, I felt
inspired to check out what Veloren's network packets look like. I started by
playing on the server, and running through a few different scenarios. First, I
started by just standing in the spawn village. Then, I started flying over
unexplored territory. Finally, I fell into a lake and sank to the bottom.

{{
  img(src="https://cdn.discordapp.com/attachments/541307708146581519/712288022338732062/Screenshot_from_2020-05-19_08-50-22.png",
  caption="")
}}

## Initial Server Connection

At first, we have a high burst of data being sent and received while connecting
to the server. Upon analysis of the packets in that region of time, we find that
many packets are making up a larger message. This message appears to be between
30KB up to around 100KB.

## Standing in Spawn Village

Here we see two different sections. First, when you load in, you start
downloading many chunks of the surrounding area. This sees about 600KB/s of
bandwidth use. Once all of the surrounding chunks have been downloaded, the
bandwidth goes down to around 300KB/s. There are still packets being sent that
update us on all of the entities around us.

{{
  img(src="https://cdn.discordapp.com/attachments/597826574095613962/711703389804953710/screenshot_1589655382942.png")
}}

## Flying Over Unexplored Areas

Similar to the previous chunk downloading, we start asking the server for more
areas. We can see that there are some larger and smaller amounts being
downloaded. This section stays quite consistent.

## Sinking in a Lake

Finally, we see a large drop in the data being sent from the server. All of the
chunks around us have already been downloaded. Also, there aren't as many
entities around us as in the village, and so we don't get as many updates. Here
we are only seeing around 60KB/s of incoming data.

{{
  img(src="https://media.discordapp.net/attachments/541307708146581519/712334298400686163/unknown.png",
  caption="Recived data rate from server")
}}

In the coming weeks, I hope to get more into the code behind networking in
Veloren. I'm also going to be exploring how we handle authentication, which
might include another writeup on some of it's concepts.

{{
  img(src="https://cdn.discordapp.com/attachments/541307708146581519/712295605170602075/logo.png",
  caption="The new banner for our Gitlab repo. See you next week!")
}}

{{ support() }}

repository: veloren/site

repo_name: veloren/site