kasuのブログ

勉強していく

Amplify AppSync 自動生成したコードのsubscriptionで引数を利用する。

Amplify AppSync

amplify add apiを行った時に、クエリ・ミューテーション・サブスクリプション用のコードを自動生成するか聞かれます。これは、自動生成を行った場合に悩んだ箇所です。

生成もとのschemaが以下

type Subscription {
  onCreateMessage(roomId: ID!): Message
    @aws_subscribe(mutations: ["createMessage"])
}

そして生成されたsubscriptionがこれ。

見て分かる通り、graphql内でroomIdを使用しているが引数などを指定する箇所が無い。

  OnCreateMessageListener: Observable<
    OnCreateMessageSubscription
  > = API.graphql(
    graphqlOperation(
      `subscription OnCreateMessage($roomId: ID!) {
        onCreateMessage(roomId: $roomId) {
          __typename
          id
          content
          when
          roomId
          owner
          room {
            __typename
            id
            createdAt
            updatedAt
          }
        }
      }`
    )
  ) as Observable<OnCreateMessageSubscription>;

GitHubのIssueには、引数に対応したコードの生成機能は無く未対応だと書いてあった。

github.com

上記のIssue内にあった対処方法を利用することにした。

自動生成されたコードをいじりたくなかったので、生成されたクラスを拡張して新たにサブスクリプション用の関数を作ることにした。

import {OnCreateMessageSubscription, APIService} from "./API.service";
import API, {graphqlOperation} from "@aws-amplify/api";
import * as Observable from "zen-observable";
import {Injectable} from "@angular/core";

@Injectable({
  providedIn: "root"
})
export class MyAPIService extends APIService {
  constructor() {
    super();
  }

  MyOnCreateMessageListener(
    roomId: string
  ): Observable<OnCreateMessageSubscription> {
    const statement = `subscription OnCreateMessage($roomId: ID!) {
        onCreateMessage(roomId: $roomId) {
          __typename
          id
          content
          when
          roomId
          owner
          room {
            __typename
            id
            createdAt
            updatedAt
          }
        }
      }`;
    const gqlAPIServiceArguments: any = {
      roomId
    };
    return API.graphql(
      graphqlOperation(statement, gqlAPIServiceArguments)
    ) as Observable<OnCreateMessageSubscription>;
  }
}

使用例

import {MyAPIService} from "../API.my";
// Subscribe to creation of Message
const messageSubscription = this.api.MyOnCreateMessageListener(this.roomid);
messageSubscription.subscribe({
  next: newMessage => {
        this.messages.push(newMessage.value.data.onCreateMessage);
  }
});

実際のリポジトリ

github.com

angular amplify publishで403 forbidden

Angular Amplify

amplify publishを行なった場合にデプロイが終わり、配信ページを訪れるとforbidden になる。

原因は、初期設定でbuild先がdist/プロジェクト名になっているから。

angular.json内のbuildオプションを編集します。

{
  "projects": {
    "ng-chat": {
      "architect": {
        "build": {
          "options": {
            "outputPath": "dist/ng-chat"

これを、distのみに編集します。

{
  "projects": {
    "ng-chat": {
      "architect": {
        "build": {
          "options": {
            "outputPath": "dist"

Redbubbleでステッカー達を購入しました :)

Gopherくん 第二弾!

第二弾です。

残すところ、あと一弾...泣

www.instagram.com

#gopher #nuxt #github #redbubble

Redbubble

Awesome products designed by independent artists | Redbubble

Gopherくんだけじゃなくて、nuxtも欲しいなあと探してて見つけました。

www.redbubble.com

www.redbubble.com

www.redbubble.com

StickerMule Unixstickers を購入しました :)

Gopherくん 第一弾!

第一弾です。

第三弾まであります :)

www.instagram.com

#golang #gopher #stickermule #macbookpro #sticker

StickerMule

ステッカーパックが1ドルで買えるとTwitterで見かけたので、今更ながら買いました。

そのおかげで、色々欲しくなってしまい第三弾まで出来てしまいました。orz

www.stickermule.com

競プロ golang 複数行文字列を配列で返してテストで使う

複数行文字列をリストにしたい

パッケージ化しました

github.com

インストール
go get github.com/ergofriend/ml2array
使い方
input := `4 5 2
0 1 2 1
0 2 1 2
1 2 1 1
1 3 1 3
2 3 2 1`

result := ml2array.Make(input)

for i := 0; i < len(result); i++ {
    fmt.Printf("%d行目:%s\n", i, result[i])
}

やっていく

現在のテストコード

現在のテストコードは1行ずつリストで足していくやり方です。

func getTests() []testValue {
    testValues := []testValue{
        testValue{
            []string{
                "3 6",
                "3 4 5",
            },
            "2"},
    }
    return testValues
}

しかし、競プロなどで例として載っけられているテストケースは複数行のテキストです。

↓こんな感じ

Image from Gyazo

これを一回でコピペしてテスト出来るようししていきます。

複数行文字列

goでは、こんな風に書きます。

input := `4 5 2
0 1 2 1
0 2 1 2
1 2 1 1
1 3 1 3
2 3 2 1`

まずappend等での速度低下をなくすために、行数を数えて必要な大きさのスライスを作成します。

var lineCount int
for i := range input {
    if input[i] == 10 {
        lineCount++
    }
}
resultArray := make([]string, lineCount)

最後に、各行をスライスに代入します。

var i int

scanner := bufio.NewScanner(strings.NewReader(mlstring))
for scanner.Scan() {
    resultArray[i] = scanner.Text()
    i++
}

終わりのテストコード

関数化して使いやすくします。

func getTests() []testValue {
    testValues := []testValue{
        testValue{
            ml2array.Make(`4 5 2
0 1 2 1
0 2 1 2
1 2 1 1
1 3 1 3
2 3 2 1`),
            "2"},
    return testValues
}

完成!

ハードウェア乱数生成

Image from Gyazo

ハードウェア乱数生成

/dev/urandom を使ってランダムなパスワードを生成する方法を読むと、

>env LC_ALL=C tr -dc a-zA-Z0-9 < /dev/random | fold -w 20 |head -1
6drFed868QT6LGyiwqUU

/dev/random

/dev/randomから読み込んだ中には記号も含まれているので、isalnum(buf[i])で文字・数字だけを出力しています。

>gcc makepasswd.c -o makepasswd
>./makepasswd
htC7LG0wjqE1XPo16AGasqLIELhlpyOJp
#include <stdio.h>

int isalnum();

int main()
{
    FILE *fp;
    char buf[128];

    fp = fopen("/dev/random", "rb");
    // fread(保存先, 保存する大きさ,  保存する大きさの個数,読み込み元)
    fread(buf, sizeof(buf), 1, fp);
    for (int i = 0; i < sizeof(buf); i++)
    {
        if (isalnum(buf[i]))
            printf("%c", buf[i]);
    }
    printf("\n");
    return 0;
}

パフォーマンスメトリック

ホップごとの遅延値

  • proc_delay: 処理遅延 (Processing delay)
  • queue_delay: 渋滞遅延 (Queueing delay)
  • link_distance: リンクの距離(Link distance)
  • propagation_speed:リンクの伝播スピード(propagation speed)
  • pkt_len: パケットサイズ(Packet size)
  • transmission_rate: リンクの伝送速度(Transmission rate)

伝播遅延(Propagation_delay) = link_distance / propagation_speed

伝送遅延(Transmission_dalay) = Packet_size / transmission_rate

ホップごとの遅延値(Per-hop delay)[ms] = proc_delay + queue_delay + Propagation_delay + Transmission_dalay

#include <stdio.h>
#include <stdlib.h>

float per_hop_delay(float proc_delay, float queue_delay, float link_distance, float propagation_speed, float pkt_len, float transmission_rate)
{
   float transmission_dalay;
   float propagation_delay;
   transmission_dalay = pkt_len / transmission_rate;      //伝送遅延
   propagation_delay = link_distance / propagation_speed; //伝播遅延
   return proc_delay + queue_delay + propagation_delay + transmission_dalay;
}

void main(int argc, char *argv[])
{
   float proc_delay = atoi(argv[1]);
   float queue_delay = atoi(argv[2]);
   float link_distance = atoi(argv[3]);
   float propagation_speed = atoi(argv[4]);
   float pkt_len = atoi(argv[5]);
   float transmission_rate = atoi(argv[6]);
   printf("per_hop_delay= %f ms\n", per_hop_delay(proc_delay, queue_delay, link_distance, propagation_speed, pkt_len, transmission_rate));
}

gcc per-hop-delay.ca.outコンパイル

例題

  • 処理遅延 (Processing delay) = 0.1 ms
  • 渋滞遅延 (Queueing delay)= 20 ms
  • リンクの距離(Link distance)= 200 km
  • リンクの伝播スピード(Propagation speed)= 3・10 ^ 8 m/s
  • パケットサイズ(Packet size) = 1500 bytes
  • 10 Mbps Ethernet Link (リンクの伝送速度(Transmission rate)= 100 Mbps)

単位をそろえて実行する。

> ./a.out 0.1 20 1000000 300000000 1500 10000000
per_hop_delay= 20.003485 ms