Read performance

I'm looking to switch to blinkdb for its typescript support, but when I benchmark indexed search, blinkdb comes out substantially slower than lokijs:
var Benchmark = require('benchmark')
const Loki = require('lokijs')
const { createDB, createTable } = require( "blinkdb")
const { internalInsertMany } = require('blinkdb/dist/core/insertMany')
const { internalFirst } = require('blinkdb/dist/core/first')

const items = require('./mock.json')

const blinkdb = createDB()
const blinktable = createTable(blinkdb, 'citekeys')({
  primary: "id",
  indexes: ["firstmail"],
});
internalInsertMany(blinktable, items)

const DB = new Loki('better-bibtex', {})
const coll = DB.addCollection('citekeys', {
  indices: [ 'id', 'firstname' ],
  unique: [ 'id' ],
})
coll.insert(items)

var suite = new Benchmark.Suite;
suite
  .add('loki', function() { coll.findOne({ firstname: { $eq: `${Math.random()}` } }) })
  .add('blink', function() { internalFirst(blinktable, { where: { firstname: `${Math.random()}` } }) })
  .on('cycle', function(event) { console.log(String(event.target)) })
  .on('complete', function() { console.log('Fastest is ' + this.filter('fastest').map('name')); })
  .run();

(where mock.json has this content)
returns
loki x 1,466,141 ops/sec ±1.39% (84 runs sampled)
blink x 1,279 ops/sec ±1.49% (89 runs sampled)

and even when I turn off indexes in loki, it still comes out ahead:
loki x 18,342 ops/sec ±0.97% (95 runs sampled)
blink x 1,313 ops/sec ±1.29% (92 runs sampled)
Fastest is loki

I haven't tested more complex searches but search by single indexed field is something I'd be doing a fair bit of. Is this just not a good use-case for blinkdb?

First issue I see is that you're creating a BlinkDB index on firstmail instead of firstname.
But I'll take a look at the query performance without indexes, BlinkDB shouldn't be 18x as slow as Loki when you search for a single key.

Oopsie.
Both indexed:
loki x 1,501,305 ops/sec ±1.24% (90 runs sampled)
blink x 1,290,563 ops/sec ±0.93% (92 runs sampled)
Fastest is loki

Both unindexed:
loki x 17,738 ops/sec ±2.96% (91 runs sampled)
blink x 1,158 ops/sec ±6.18% (82 runs sampled)
Fastest is loki

I'm also not seeing the performance in the sample from the front-page; unless I mucked it up again, I'm getting this (script below):

search should find 52 users
sharding x 1,900,158 ops/sec ±1.74% (88 runs sampled)
loki x 43,503 ops/sec ±1.61% (87 runs sampled)
blinkdb x 982 ops/sec ±1.05% (82 runs sampled)
Fastest is sharding

script:
var Benchmark = require('benchmark');
const Loki = require('lokijs')
const { createDB, createTable, insertMany, many } = require( "blinkdb")

// data at https://gist.github.com/retorquere/c71d72f63a6a79ad3d0f6cd217e71b03
const items = require('./mock.json')

async function main() {
  const blinkdb = createDB()
  const blinktable = createTable(blinkdb, 'users')({
    primary: "id",
    indexes: ["age", "name"],
  });
  await insertMany(blinktable, items)

  const DB = new Loki('better-bibtex', {})
  const coll = DB.addCollection('citekeys', {
    indices: [ 'id', 'age', 'name' ],
    unique: [ 'id' ],
  })
  coll.insert(items)

  var suite = new Benchmark.Suite()

  const names = ['Davies', 'Gosling']
  const age = 24
  const n = items.filter(item => item.age > age && names.includes(item.name)).length
  console.log('search should find', n, 'users')

  const shards = new Map
  for (const user of items) {
    if (!shards.has(user.name)) {
      shards.set(user.name, [ user ])
    }
    else {
      shards.get(user.name).push(user)
    }
  }

  suite
    .add('sharding', function() {
      let found = []
      for (const name of names) {
        found = found.concat((shards.get(name) || []).filter(user => user.age > age))
      }
      if (found.length !== n) throw new Error('')
    })
    .add('loki', function() {
      if (coll.find({ name: { $in: names }, age: { $gt: age } }).length !== n) throw new Error('')
    })
    .add('blinkdb', {
      defer: true,
      fn: async function(deferred) {
        if ((await many(blinktable, { where: { name: { in: names }, age: { gt: age } }, })).length !== n) throw new Error('')
        deferred.resolve()
      }
    })
    .on('cycle', function(event) { console.log(String(event.target)) })
    .on('complete', function() {
      console.log('Fastest is ' + this.filter('fastest').map('name'));
    })
    .run({ async: true });
}

main()

And for 100.000 items (as per the case on the front page):

search should find 3 users
scan x 1,139,156 ops/sec ±1.15% (88 runs sampled)
sharding x 3,938,455 ops/sec ±3.28% (84 runs sampled)
loki x 255,922 ops/sec ±0.82% (90 runs sampled)
blinkdb x 119,386 ops/sec ±1.09% (79 runs sampled)
Fastest is sharding

Is the benchmark from the front page in the benchmark suite? I can't find it but I'd love to tinker around with it. My numbers don't align with that graph at all, so there must be something relevantly different between how these tests are set up.

Changed to tinybench like the blinkdb tests:
const { Bench } = require('tinybench');
const Loki = require('lokijs')
const { createDB, createTable, insertMany, many } = require( "blinkdb")

// data at https://gist.github.com/retorquere/c71d72f63a6a79ad3d0f6cd217e71b03
const items = require('./mock.json')

async function main() {
  const blinkdb = createDB()
  const blinktable = createTable(blinkdb, 'users')({
    primary: "id",
    indexes: ["age", "name"],
  });
  await insertMany(blinktable, items)

  const DB = new Loki('better-bibtex', {})
  const coll = DB.addCollection('citekeys', {
    indices: [ 'id', 'name', 'age' ],
    unique: ['id'],
  })
  coll.insert(items)

  var bench = new Bench

  const random = () => items[Math.round(Math.random() * items.length)]
  const names = [ random().name, random().name ]
  const age = random().age
  const n = items.filter(item => item.age > age && names.includes(item.name)).length
  console.log('> search should find', n, 'users')

  const partitions = new Map
  for (const user of items) {
    if (!partitions.has(user.name)) {
      partitions.set(user.name, [ user ])
    }
    else {
      partitions.get(user.name).push(user)
    }
  }

  bench
    .add('scan', function() {
      if (items.filter(item => item.age > age && names.includes(item.name)).length !== n) throw new Error('')
    })
    .add('partitions', () => {
      let found = []
      for (const name of names) {
        found = found.concat((partitions.get(name) || []).filter(user => user.age > age))
      }
      if (found.length !== n) throw new Error('')
    })
    .add('loki', () => {
      if (coll.find({ name: { $in: names }, age: { $gt: age } }).length !== n) throw new Error('')
    })
    .add('blinkdb', async () => {
      if ((await many(blinktable, { where: { name: { in: names }, age: { gt: age } }, })).length !== n) throw new Error('')
    })

  await bench.run()
  console.table(bench.table())
}

main()

(index)
Task Name
ops/sec
Average Time (ns)
Margin
Samples

0
'scan'
'505'
1978472.635444445
'±1.45%'
253

1
'partitions'
'386,787'
2585.400346700469
'±1.11%'
193440

2
'loki'
'8,665'
115399.97140832458
'±0.63%'
4333

3
'blinkdb'
'140'
7106147.1843383685
'±3.94%'
71

Thanks for taking a look at this :) If you check the official benchmarks for BlinkDB, do you get similar results there (with BlinkDB consistently being slower than alternatives) ? The blinkdb benchmarks only compare my DB to LokiJS, but in my test runs BlinkDB generally reaches 0.8x - 1.2x of the performance of LokiJS, depending on the testcase.
I'll try implementing your testcase within the BlinkDB benchmarks from scratch, then we can see if there's any issues on either side.

Is the benchmark from the front page in the benchmark suite?

Not really, I either did that manually a few versions ago or deleted it from the benchmarks in the last refactor. In either case, I should add it back in and update the values on the front page.

I added a benchmark myself, available on the feature/add-front-page-test branch here: https://github.com/blinkdb-js/blinkdb/blob/feature/add-front-page-test/packages/benchmarks/src/benchmarks/blinkdb/front-page.ts
My results look like this:
┌─────────┬───────────┬────────────────────┬────────────────────┬──────────┬─────────┐
│ (index) │   name    │      ops/sec       │ Average Time (ns)  │  Margin  │ Samples │
├─────────┼───────────┼────────────────────┼────────────────────┼──────────┼─────────┤
│    0    │   'map'   │ 12863.936992022735 │  77736.6991629488  │ '±1.31%' │  6432   │
│    1    │  'scan'   │ 3202.195645886974  │<PHONE_NUMBER>7647185 │ '±2.09%' │  1602   │
│    2    │ 'lokijs'  │ 1577.6523390569928 │<PHONE_NUMBER>959788  │ '±2.84%' │   789   │
│    3    │ 'blinkdb' │ 1561.9037649061502 │<PHONE_NUMBER>21234  │ '±4.42%' │   781   │
└─────────┴───────────┴────────────────────┴────────────────────┴──────────┴─────────┘

Comparing our respective implementations, a few things I noticed:

Both BlinkDB and LokiJS have the option to clone returned objects. In BlinkDB this is turned on by default, in LokiJS off by default. Since I don't care about comparing the speed of clone implementations, I turn this off for BlinkDB in my benchmarks with createDB({ clone: false });. This doubles the performance of BlinkDB in this specific benchmark for me.
Your scan is particularly slow, and your map/partitions particularly fast compared to mine. I haven't found a specific reason for this yet.

Testing with your dataset gets me a benchmark more comparable to yours, but BlinkDB is somehow still faster on my side.

My code
import { createDB, createTable, insertMany, many } from "blinkdb";
import loki from "lokijs";
import { Bench } from "tinybench";
// Same content as https://gist.github.com/retorquere/c71d72f63a6a79ad3d0f6cd217e71b03
import userJson from "./users.json";

interface User {
  id: number;
  name: string;
  // made age non-optional here
  age: number;
}

const blinkdb = createDB({ clone: false });
let blinkUserTable = createTable<User>(blinkdb, "users")({
  primary: "id",
  indexes: ["name", "age"] // added age index
});

const lokidb = new loki("users.db");
let lokiUserTable = lokidb.addCollection<User>("users", {
  unique: ["id"],
  indices: ["name", "age"] // added age index
});

let users: User[] = userJson;
let userMap: Map<string, User[]> = new Map();
for(const user of users) {
  userMap.set(user.name, [...(userMap.get(user.name) ?? []), user]);
}
lokiUserTable.insert(users);
insertMany(blinkUserTable, users);

const random = () => users[Math.round(Math.random() * users.length)];
const names = [random().name, random().name];
const age = random().age;

export const bench = new Bench()
  .add("scan", () => {
    users.filter(u => names.includes(u.name) && u.age && u.age > age);
  })
  .add("map", () => {
    let u: User[] = [];
    for(const name of names) {
      u = u.concat((userMap.get(name) ?? []).filter(u => u.age && u.age > age));
    }
  })
  .add("lokijs", () => {
    lokiUserTable.find({ name: { $in: names }, age: { $gt: age } });
  })
  .add("blinkdb", async () => {
    await many(blinkUserTable ,{ where: {
      name: { in: names },
      age: { gt: age }
    }});
  });

blinkdb/front-page.ts --- map is 42.64x faster than lokijs
┌─────────┬───────────┬────────────────────┬────────────────────┬──────────┬─────────┐
│ (index) │   name    │      ops/sec       │ Average Time (ns)  │  Margin  │ Samples │
├─────────┼───────────┼────────────────────┼────────────────────┼──────────┼─────────┤
│    0    │   'map'   │ 1489335.8240912817 │<PHONE_NUMBER>725764  │ '±1.76%' │ 744668  │
│    1    │ 'lokijs'  │ 34925.248617732905 │ 28632.580713892505 │ '±1.07%' │  17463  │
│    2    │ 'blinkdb' │ 29151.137594377647 │ 34303.978593029904 │ '±3.88%' │  14576  │
│    3    │  'scan'   │ 2969.203635917305  │<PHONE_NUMBER>144804  │ '±0.64%' │  1485   │
└─────────┴───────────┴────────────────────┴────────────────────┴──────────┴─────────┘

How do you run this? I'm getting

Cannot use import statement outside a module

when I start it with npx ts-node.

If you check the official benchmarks for BlinkDB, do you get similar results there (with BlinkDB consistently being slower than alternatives) ?

I haven't been able to get them to work yet.

and running npm run start -- "blinkdb/front-page.ts" .

That gets me
Unknown file extension ".ts" for /Users/emile/github/blinkdb/packages/benchmarks/src/index.ts

Both BlinkDB and LokiJS have the option to clone returned objects. In BlinkDB this is turned on by default, in LokiJS off by default.

That is true. But when I turn clone off for blinkDB, my tests continue to show everything faster than blinkdb.

 Nothing should be slower than a full scan.

and your map/partitions particularly fast compared to mine. I haven't found a specific reason for this yet.

Javascript Map is just ridiculuously fast, and after selection of the partition it's all integer comparisons. It's doing half the work, and the fast half at that.
I was working on a lokijs partition command where you could select one partition and then filter on the much smaller resultset as usual. But lokijs has not been active for a long while, and I'd much prefer to move to blinkdb if we can get this apparent disparity sorted out.

Testing with your dataset gets me a benchmark more comparable to yours, but BlinkDB is somehow still faster on my side.

Well now... I've gotten this script to run and I'm now getting

(index)
Task Name
ops/sec
Average Time (ns)
Margin
Samples

0
'scan'
'503'
1987200.3532576538
'±0.44%'
252

1
'map'
'306,251'
3265.293322546093
'±2.15%'
153126

2
'lokijs'
'9,114'
109709.38964793888
'±1.07%'
4558

3
'blinkdb'
'20,498'
48784.63455380463
'±1.24%'
10250

And this is the same script with clone on on both:

(index)
Task Name
ops/sec
Average Time (ns)
Margin
Samples

0
'scan'
'483'
2066123.4032791948
'±0.46%'
243

1
'map'
'511,727'
1954.164901172087
'±2.96%'
255864

2
'lokijs'
'1,874'
533549.3187751692
'±0.59%'
938

3
'blinkdb'
'18,850'
53049.23583965835
'±0.84%'
9426

How does cloning make such a big difference when a search returns so few records? There is no cloning during the search right, just for the hits that are returned from the search?

and your map/partitions particularly fast compared to mine. I haven't found a specific reason for this yet.

I would imagine that partitions could implemented as hooks on insert/update/create/delete that would maintain T[] records in a Map keyed on the partition field values, and that there would be an equivalent for get that would return that partition T[]. These are not as flexible as general query methods (you can use them only at the start of the query chain) but given the results in these benchmarks they would provide a massive performance benefit where you can use them (and I have such a use case).

and running npm run start -- "blinkdb/front-page.ts" .

I can just run "npm run test" on the toplevel -- that works.

This is approximately what I meant by adding partition support to blinkdb:
const { createDB, createTable, insertMany, many, use, key } = require( "blinkdb")
const loki = require( "lokijs" )
const { Bench } = require( "tinybench")
// Same content as https://gist.github.com/retorquere/c71d72f63a6a79ad3d0f6cd217e71b03
const users  = require( "./users.json" )

const blinkdb = createDB({ clone: true })
const blinkPartition = new Map
let blinkUserTable = createTable(
  blinkdb,
  "users"
)({
  primary: "id",
  indexes: ["name", "age"] // added age index
})

const lokidb = new loki("users.db")
let lokiUserTable = lokidb.addCollection("users", {
  unique: ["id"],
  indices: ["name", "age"], // added age index
  clone: true
})

  function mapRemove(entry, partition, pk) {
    if (blinkPartition.has(entry[partition])) {
      blinkPartition.get(entry[partition]).delete(entry[pk])
      if (blinkPartition.get(entry[partition]).size === 0) blinkPartition.delete(entry[partition])
    }
  }

  function mapAdd(entry, partition, pk) {
    if (!blinkPartition.has(entry[partition])) blinkPartition.set(entry[partition], new Map)
    blinkPartition.get(entry[partition]).set(entry[pk], entry)
  }

  use(blinkUserTable, async (ctx) => {
    switch (ctx.action) {
      case 'update':
      case 'delete':
        var pk = key(ctx.params[0])
        mapRemove(one(ctx.params[0], ctx.params[1][pk]), 'name', pk)
        break
      case 'updateMany':
      case 'deleteMany':
        var pk = key(ctx.params[0])
        for (const entry of ctx.params[1]) {
          mapRemove(one(ctx.params[0], entry[pk]), 'name', pk)
        }
    }

    const result = await ctx.next(...ctx.params);

    switch (ctx.action) {
      case 'update':
      case 'insert':
        var pk = key(ctx.params[0])
        mapAdd(ctx.params[1], 'name', pk)
        break
      case 'updateMany':
      case 'insertMany':
        var pk = key(ctx.params[0])
        for (const entry of ctx.params[1]) {
          mapAdd(entry, 'name', pk)
        }
    }
  });

lokiUserTable.insert(users)
insertMany(blinkUserTable, users)

const random = () => users[Math.round(Math.random() * users.length)]
const names = [random().name, random().name]
const age = random().age

async function main() {
const bench = new Bench()
  .add("scan", () => {
    users.filter(u => names.includes(u.name) && u.age && u.age > age)
  })
  .add("blinkdb partition", () => {
    let found = []
      for (const name of names) {
        const partition = blinkPartition.get(name)
        if (partition) found = found.concat([...partition.values()].filter(user => user.age > age))
      }
  })
  .add("lokijs", () => {
    lokiUserTable.find({ name: { $in: names }, age: { $gt: age } })
  })
  .add("blinkdb", async () => {
    await many(blinkUserTable, {
      where: {
        name: { in: names },
        age: { gt: age }
      }
    })
  })

await bench.run();

console.table(bench.table());
}

main()

(index)
Task Name
ops/sec
Average Time (ns)
Margin
Samples

0
'scan'
'389'
2564482.030692773
'±1.47%'
195

1
'blinkdb partition'
'316,342'
3161.130628320554
'±1.28%'
158172

2
'lokijs'
'2,191'
456255.7216013109
'±0.89%'
1096

3
'blinkdb'
'12,512'
79922.36493746274
'±1.13%'
6257

I must admit your use of typescript is a lot more advanced than mine; what I had envisioned was something along the lines of
const items = await many(userTable, {
  where: {
    name: { partition: ["Alice", "Charlie"] },
    age: { gt: 24 },
  },
});

but I've run aground in adding this to the query evaluation.
Is it correct that get is synchronous? I could write my own wrapper to implement one and many to get sync reads?

If you need an array of items from the DB that is regenerated whenever items are inserted/updated/deleted, you don't need to implement partitions, you can just use watch. This gets you the fastest possible speed on read operations by adding small performance hits to every write.

Your benchmark with `watch`
const { createDB, createTable, insertMany, many, use, key, watch } = require( "blinkdb")
const { clone } = require('blinkdb/dist/core/clone')
const loki = require( "lokijs" )
const { Bench } = require( "tinybench")
// Same content as https://gist.github.com/retorquere/c71d72f63a6a79ad3d0f6cd217e71b03
const users  = require( "./users.json" )

const blinkdb = createDB({ clone: true })
const blinkPartition = new Map
let blinkUserTable = createTable(
    blinkdb,
    "users"
)({
    primary: "id",
    indexes: ["name", "age"] // added age index
})

const lokidb = new loki("users.db")
let lokiUserTable = lokidb.addCollection("users", {
    unique: ["id"],
    indices: ["name", "age"], // added age index
    clone: true
})

function mapRemove(entry, partition, pk) {
    if (blinkPartition.has(entry[partition])) {
        blinkPartition.get(entry[partition]).delete(entry[pk])
        if (blinkPartition.get(entry[partition]).size === 0) blinkPartition.delete(entry[partition])
    }
}

function mapAdd(entry, partition, pk) {
    if (!blinkPartition.has(entry[partition])) blinkPartition.set(entry[partition], new Map)
    blinkPartition.get(entry[partition]).set(entry[pk], entry)
}

use(blinkUserTable, async (ctx) => {
    switch (ctx.action) {
        case 'update':
        case 'delete':
            var pk = key(ctx.params[0])
            mapRemove(one(ctx.params[0], ctx.params[1][pk]), 'name', pk)
            break
        case 'updateMany':
        case 'deleteMany':
            var pk = key(ctx.params[0])
            for (const entry of ctx.params[1]) {
                mapRemove(one(ctx.params[0], entry[pk]), 'name', pk)
            }
    }

    const result = await ctx.next(...ctx.params);

    switch (ctx.action) {
        case 'update':
        case 'insert':
            var pk = key(ctx.params[0])
            mapAdd(ctx.params[1], 'name', pk)
            break
        case 'updateMany':
        case 'insertMany':
            var pk = key(ctx.params[0])
            for (const entry of ctx.params[1]) {
                mapAdd(entry, 'name', pk)
            }
    }
    return result
});

const random = () => users[Math.round(Math.random() * users.length)]
const names = [random().name, random().name]
const age = random().age

let watchUsers = [];
watch(blinkUserTable, {
    where: {
        name: { in: names },
        age: { gt: age }
    }
}, users => watchUsers = users)

lokiUserTable.insert(users)
insertMany(blinkUserTable, users)

async function main() {
    const bench = new Bench()
        .add("scan", () => {
            const u = users.filter(u => names.includes(u.name) && u.age && u.age > age);
        })
        .add("partition", () => {
            let found = []
            for (const name of names) {
                const partition = blinkPartition.get(name)
                if (partition) found = found.concat([...partition.values()].filter(user => user.age > age)).map(clone)
            }
        })
        .add("watch", () => {
            watchUsers
        })
        .add("lokijs", () => {
            const l = lokiUserTable.find({ name: { $in: names }, age: { $gt: age } })
        })
        .add("blinkdb", async () => {
            const b = await many(blinkUserTable, {
                where: {
                    name: { in: names },
                    age: { gt: age }
                }
            })
        })

    await bench.run();

    console.table(bench.table());
}

main()

How does cloning make such a big difference when a search returns so few records? There is no cloning during the search right, just for the hits that are returned from the search?

Can't speak for LokiJS, but BlinkDB only clones items returned from a call to get.

Is there a general hook for "each deleted(/inserted/updated) entry" regardless of whether it was called through removeMany/remove/removeWhere?

watch(...) does that. It's basically a simplified use(...) hook.

Is it correct that get is synchronous? I could write my own wrapper to implement one and many to get sync reads?

Yes. The entire query engine is synchronous. BlinkDB is just async in order to support async middleware.

If you need an array of items from the DB that is regenerated whenever items are inserted/updated/deleted, you don't need to implement partitions, you can just use watch. This gets you the fastest possible speed on read operations with small performance hits on every write.

That's not entirely the same though. With the partition solution, you get the speedup without knowing the names in advance. The watch as used here only works if you know up front which names you're going to select. I need something where the names can be arbitrary. As far as I can tell, this watch setup would only work if I rebuilt the partitions for every mutation, which is going to be prohibitive for large tables. The map approach I posted only makes one or two changes to the map for each mutation, rather than rebuilding it.

watch(...) doesn't give you the "changed" items (yet), but it does give you all items that match a given query. It's basically a simplified use(...) hook.

I do need the changed/deleted/added items though, as I use them in my own event handling. How would I implement my use on a removeWhere? I would have to run the query again before the call to ctx.next I suppose?

Yes. The entire query engine is synchronous. BlinkDB is just async in order to support async middleware.

Gotcha -- that is not a problem for me, I just need read/search to be sync, so I can start working on blink integration.

I'm trying to understand how the query infrastructure works, is there any documentation on the design of it?

I do need the changed/deleted/added items though, as I use them in my own event handling. How would I implement my use on a removeWhere? I would have to run the query again before the call to ctx.next I suppose?

I think it best to implement this in watch already. The callback could simply provide a diff argument which either contains the elements that were added, updated, or deleted that triggered the watch hook.
If you want to implement this using removeWhere, you could use the query engine yourself (the get, although I don't know if that API is publicly exposed yet) to retrieve all items that match the where filter, then perform some operation on them, then pass them to ctx.next.

I think it best to implement this in watch already. The callback could simply provide a diff argument which either contains the elements that were added, updated, or deleted that triggered the watch hook.

That would work.

If you want to implement this using removeWhere, you could use the query engine yourself (the get, although I don't know if that API is publicly exposed yet)

Sort of -- I can fetch it using import { get } from 'blinkdb/src/query'

to retrieve all items that match the where filter, then perform some operation on them, then pass them to ctx.next.

I'd much prefer the former option :)

Looks like in the interim I could just subscribe to the dispatcher using
table[BlinkKey].events.onInsert.register((changes) => console.log(changes))
table[BlinkKey].events.onUpdate.register((changes) => console.log(changes))
table[BlinkKey].events.onRemove.register((changes) => console.log(changes))
table[BlinkKey].events.onClear.register((changes) => console.log(changes))

correct?

Me again -- I took your last script and modified it (to avoid screwups like before) for a new case I'm working on, script + data are at here, but I'm getting this for single-field indexed lookup:
┌─────────┬───────────┬──────────┬───────────────────┬──────────┬─────────┐
│ (index) │ Task Name │ ops/sec  │ Average Time (ns) │ Margin   │ Samples │
├─────────┼───────────┼──────────┼───────────────────┼──────────┼─────────┤
│ 0       │ 'lokijs'  │ '18,257' │ 54772.43624664317 │ '±0.51%' │ 9129    │
│ 1       │ 'blinkdb' │ '13,989' │ 71482.33448462115 │ '±0.25%' │ 6995    │
└─────────┴───────────┴──────────┴───────────────────┴──────────┴─────────┘

For m: { in: ['math', 'text'] } the difference is even more pronounced:
┌─────────┬───────────┬──────────┬────────────────────┬──────────┬─────────┐
│ (index) │ Task Name │ ops/sec  │ Average Time (ns)  │ Margin   │ Samples │
├─────────┼───────────┼──────────┼────────────────────┼──────────┼─────────┤
│ 0       │ 'lokijs'  │ '20,296' │ 49269.873422405995 │ '±0.51%' │ 10149   │
│ 1       │ 'blinkdb' │ '11,252' │ 88871.98824261357  │ '±0.38%' │ 5627    │
└─────────┴───────────┴──────────┴────────────────────┴──────────┴─────────┘

I've managed to get the benchmarks to run; I've taken the front-page.ts benchmark and modified it to this, so I'm pretty sure I got it right this time:
import { createDB, createTable, insertMany, many } from "blinkdb";
import loki from "lokijs";
import { Bench } from "tinybench";

interface Char {
  id: number;
  u: string;
  s: string;
  t: string;
  m: string;
  p: string;
}

const blinkdb = createDB({ clone: false });
let blinkUserTable = createTable<Char>(blinkdb, "users")({
  primary: "id",
  indexes: [ 'u', 's', 't', 'm', 'p' ],
});

const lokidb = new loki("users.db");
let lokiUserTable = lokidb.addCollection<Char>("users", {
  unique: ["id"],
  indices: [ 'u', 's', 't', 'm', 'p' ],
});

let chars = require('./config2.json')
chars.forEach((char: Char, i: number) => char.id = i)

lokiUserTable.insert(chars);
insertMany(blinkUserTable, chars);

export const bench = new Bench()
  .add("lokijs", () => {
    lokiUserTable.find({ m: { $in: ["m", "t"] } });
  })
  .add("blinkdb", async () => {
    await many(blinkUserTable ,{ where: {
      m: { in: ["m", "t"] },
    }});
  });

and there lokijs gets over twice the performance of blinkdb:
┌─────────┬───────────┬────────────────────┬────────────────────┬───────────┬─────────┐
│ (index) │   name    │      ops/sec       │ Average Time (ns)  │  Margin   │ Samples │
├─────────┼───────────┼────────────────────┼────────────────────┼───────────┼─────────┤
│    0    │ 'lokijs'  │ 4495.033687905337  │<PHONE_NUMBER>6523422 │ '±4.68%'  │  2248   │
│    1    │ 'blinkdb' │ 1990.6891247726794 │<PHONE_NUMBER>413586  │ '±12.03%' │   996   │
└─────────┴───────────┴────────────────────┴────────────────────┴───────────┴─────────┘

with front-page.ts I get the expected
┌─────────┬───────────┬────────────────────┬────────────────────┬───────────┬─────────┐
│ (index) │   name    │      ops/sec       │ Average Time (ns)  │  Margin   │ Samples │
├─────────┼───────────┼────────────────────┼────────────────────┼───────────┼─────────┤
│    0    │   'map'   │<PHONE_NUMBER>7945804 │ 4201698.067308473  │ '±1.89%'  │   119   │
│    1    │  'scan'   │<PHONE_NUMBER>8634888 │ 5579117.956426408  │ '±3.32%'  │   90    │
│    2    │ 'blinkdb' │  86.9096681550792  │ 11506199.727004224 │ '±15.91%' │   44    │
│    3    │ 'lokijs'  │ 47.70440453076051  │ 20962424.95502035  │ '±12.22%' │   24    │
└─────────┴───────────┴────────────────────┴────────────────────┴───────────┴─────────┘

with blinkdb getting almost twice the performance of lokijs.


Trunk Compiles have been broken for a number of days

Looks like compilers have not built since Aug 24. Also seems.deploys are failing with tar xz erroring out somewhere along the line.

it's a boto/aws client issue :/

1: tar xz was due to daily DMD failing. I've disabled that for now in d70f63a577b364ebb261408a0efa6e44e1d8af8a)
2. a version incompatibility in aws and boto coming from paramiko was causing issues. Python, man... hopefully fixed in 2a863ed54e20923444ec866b7ee7158131671425


Fix a typo in the executable name during precheck

i think we actually do exactly need gzip and not zip


zos: delay signal handling until after normal i/o

In https://github.com/libuv/libuv/pull/611, changes were made to AIX and other unix systems to defer the signal watcher that is used for process management until after the dispatch of regular i/o watchers.
This PR ports those changes to z/OS as well so that behavior of uv__io_poll() on z/OS is more consistent with that of the other unix platforms.

What is the flaky CI issue? While acceptable to make this change-like with the original PR-it does not fix the problems inherent in assuming this order of events

What is the flaky CI issue? While acceptable to make this change-like with the original PR-it does not fix the problems inherent in assuming this order of events

Sorry I made a mistake. The changes resolved flaky issues on AIX but it doesn't look like we have documented any related flaky issues on z/OS. With that said though, we think that it may still make sense to merge this PR for consistency with the other unix platforms.

CI: https://ci.nodejs.org/job/libuv-test-commit-zos-cmake/1333


Fix workflow_run name

workflows:must contain the name of the other workflow, not the filename

@gerw you can merge this if you have time to do so


datastructure for LIFO

Hi, to whom it may concern:
I don't understand why LIFO and FIFO are all initialized with a queue please?
It seems like operation changes when LIFO, it uses prepend, and when FIFO it uses append.
This makes the logic correct, however the names are little confusing.
https://github.com/zephyrproject-rtos/zephyr/blob/2251ea04a8eeef76f3bc4bbe58ea4132a2f67fad/include/kernel.h#L1937
struct k_lifo {
	struct k_queue _queue;
};

#define _K_LIFO_INITIALIZER(obj) \
	{ \
	._queue = _K_QUEUE_INITIALIZER(obj._queue) \
	}

#define K_LIFO_INITIALIZER DEPRECATED_MACRO _K_LIFO_INITIALIZER

@Vudentz can you please look into this, AFAIK you made changes in this area.

Well they both are using a queue as storage for the items, in fact both k_fifo and k_lifo could be replaced by k_queue, but initially lifo and fifo did not share a common storage so there was a lot of code duplication.


I want to set the depth of resnet to 18

I want to set the depth of resnet to 18.
But it occur the problem: AssertionError: FasterRCNN: ResNet: Not implemented yet.
And could you tell me how to reset the depth of resnet?

Refer to this https://github.com/open-mmlab/mmdetection/blob/f08548bfd6d394a82566022709b5ce9e6b0a855e/configs/ld/ld_r18_gflv1_r101_fpn_coco_1x.py#L11-L19

And, need i change the FPN in_channel just like this?
type='ResNet',
depth=18,
num_stages=4,
out_indices=(0, 1, 2, 3),
frozen_stages=1,
norm_cfg=dict(type='BN', requires_grad=True),
norm_eval=True,
style='pytorch',
init_cfg=dict(type='Pretrained', checkpoint='torchvision://resnet18')),
neck=dict(
type='FPN',
in_channels=[64, 128, 256, 512],
out_channels=256,
start_level=1,
add_extra_convs='on_output',
num_outs=5),

https://github.com/open-mmlab/mmdetection/blob/f08548bfd6d394a82566022709b5ce9e6b0a855e/configs/ld/ld_r18_gflv1_r101_fpn_coco_1x.py
https://github.com/open-mmlab/mmdetection/blob/f08548bfd6d394a82566022709b5ce9e6b0a855e/configs/ld/ld_r18_gflv1_r101_fpn_coco_1x.py
type='ResNet', depth=18, num_stages=4, out_indices=(0, 1, 2, 3), frozen_stages=1, norm_cfg=dict(type='BN', requires_grad=True), norm_eval=True, style='pytorch', init_cfg=dict(type='Pretrained', checkpoint='torchvision://resnet18')), neck=dict( type='FPN', in_channels=[64, 128, 256, 512], out_channels=256, start_level=1, add_extra_convs='on_output', num_outs=5),

And, need i change the FPN in_channel just like this?
https://github.com/open-mmlab/mmdetection/blob/f08548bfd6d394a82566022709b5ce9e6b0a855e/configs/ld/ld_r18_gflv1_r101_fpn_coco_1x.py#L10-L26

Yes, the input channels of FPN should also be changed.


New example

Generating a new example, using new version of expo

Urgent: Needed to fix

No worries.


[Error Report] dfitpack.error: (1<=k && k<=5) failed for 3rd argument k: fpcurf0:k=0

I ran the program with the command "$ python main.py test --exp_name laneatt_r34_tusimple --view all" and pressed a key to go through all the result images, but an error occurs when it progressed to the 2417th result (87%) every time.
If I run the command "$ python main.py test --exp_name laneatt_r34_tusimple/" without flag "--view all", the program could run successfully.
Does this issue occur to anyone? How should I solve it? Thanks!
$ python main.py test --exp_name laneatt_r34_tusimple --view all
[2020-12-19 10:14:25,366] [lib.runner] [INFO] Loading model experiments/laneatt_r34_tusimple/models/model_0100.pt
[2020-12-19 10:14:34,055] [lib.datasets.tusimple] [INFO] Loading TuSimple annotations...
[2020-12-19 10:14:34,670] [lib.datasets.tusimple] [INFO] 2782 annotations loaded, with a maximum of 5 lanes in an image.
[2020-12-19 10:14:34,671] [lib.datasets.lane_dataset] [INFO] Transforming annotations to the model's target format...
[2020-12-19 10:14:45,315] [lib.datasets.lane_dataset] [INFO] Done.
 87%|████████████████████████████████████████████████████████████████████████████████████████████████████████████████                 | 2417/2782 [08:38<01:14,  4.89it/s]
Traceback (most recent call last):
  File "main.py", line 59, in <module>
    main()
  File "main.py", line 55, in main
    runner.eval(epoch=args.epoch or exp.get_last_checkpoint_epoch(), save_predictions=args.save_predictions)
  File "/home/thlin/Code/CSIE_Project/LaneATT/lib/runner.py", line 97, in eval
    img, fp, fn = dataloader.dataset.draw_annotation(idx, img=img, pred=prediction[0])
  File "/home/thlin/Code/CSIE_Project/LaneATT/lib/datasets/lane_dataset.py", line 191, in draw_annotation
    label = self.label_to_lanes(label)
  File "/home/thlin/Code/CSIE_Project/LaneATT/lib/datasets/lane_dataset.py", line 176, in label_to_lanes
    lanes.append(Lane(points=points))
  File "/home/thlin/Code/CSIE_Project/LaneATT/lib/lane.py", line 10, in __init__
    self.function = InterpolatedUnivariateSpline(points[:, 1], points[:, 0], k=min(3, len(points) - 1))
  File "/home/thlin/.venv/LaneATT-env/lib/python3.8/site-packages/scipy/interpolate/fitpack2.py", line 611, in __init__
    self._data = dfitpack.fpcurf0(x, y, k, w=w, xb=bbox[0],
dfitpack.error: (1<=k && k<=5) failed for 3rd argument k: fpcurf0:k=0
 87%|████████████████████████████████████████████████████████████████████████████████████████████████████████████████                 | 2417/2782 [08:38<01:18,  4.66it/s]

I was able to reproduce the issue and it seems to occur on a ground-truth lane with only 2 annotated points. For some reason, after a few format conversions, only one point remains. Thus, the spline interpolation is impossible. I'll have to look into it a bit deeper to find out the reason for that, but it probably has no impact on other stuff, since that part of the code is only ran when visualizing labels.

Okay, Got it. Thank you for looking into this issue!

Hi lucastabelini,
I got the same issue when generating videos:
My command: (I previously generated the file predictions.pkl)
run utils/gen_video.py --pred predictions.pkl --cfg experiments/laneatt_r34_tusimple/config.yaml --out tusimple34.avi

It will always happen at 87%
It will also happen when using the culane dataset.

how to deal the poblem？I can not see the answer.Anyone tell me ?

I was able to reproduce the issue and it seems to occur on a ground-truth lane with only 2 annotated points. For some reason, after a few format conversions, only one point remains. Thus, the spline interpolation is impossible. I'll have to look into it a bit deeper to find out the reason for that, but it probably has no impact on other stuff, since that part of the code is only ran when visualizing labels.

have you found the truth?I still have this problem

how to deal the poblem？I can not see the answer.Anyone tell me ?

do you solve it? I still have this problem

Yes，maybe you should check every step you think important,you can use "print" to check these messages.发自我的 iPhone在 2024年3月14日，22:10，0nea @.***> 写道：
how to deal the poblem？I can not see the answer.Anyone tell me ?
do you solve it? I still have this problem
—Reply to this email directly, view it on GitHub, or unsubscribe.You are receiving this because you commented.Message ID: @.***>


Add return type hints

how did you get the right types? any way we can automate?

A lot of manual inspection 😅

Will split this PR into 3 where each change 1/ agent & clients 2/common dir 3/download dir for easier and safer rollout

Split up into the following PRs:
#1403
#1404
#1405
#1406


\e[2m not working properly

(Originally, mistakenly, posted on the asciinema.org repo.)
The dim/faint color attribute (\e[2m) doesn't show up properly in the web player.
Running this script:
#!/bin/bash

printf "\n"
printf "    _   __                           __   \e[2m______      _       __ \e[0m\n"
printf "   / | / /___  _________ ___  ____ _/ /  \e[2m/ ____/___ _(_)___  / /_\e[0m\n"
printf "  /  |/ / __ \/ ___/ __ ´__ \/ __ ´/ /  \e[2m/ /_  / __ ´/ / __ \/ __/\e[0m\n"
printf " / /|  / /_/ / /  / / / / / / /_/ / /  \e[2m/ __/ / /_/ / / / / / /_  \e[0m\n"
printf "/_/ |_/\____/_/  /_/ /_/ /_/\__,_/_/  \e[2m/_/    \__,_/_/_/ /_/\__/  \e[0m\n"
printf "\n"

Produces the expected output in a terminal:

But not in the player:

black/white: https://asciinema.org/a/4dc8adqp6ydgz4rcph4zvuucb
colored: https://asciinema.org/a/8muthjs1m0bcbo6f1c4tp8kt1

@sickill Could I work on this?

@sickill?

It also doesn't work for tools that use asciinema like svg-term.  @sickill is the idea realistic that adding support for \e[2m would be as simple as https://github.com/asciinema/vt/commit/fecc4f04c13ceb7984678cc93fa0fde2a192f042?

Just released 3.1.0 with the fix.

Fixed in 3.1.0.


I have to set permission on /tmp/fetch_binaries.sh

Before that I was receiving the error:
=> ERROR [fetcher 4/4] RUN /tmp/fetch_binaries.sh                                                                                0.9s

[fetcher 4/4] RUN /tmp/fetch_binaries.sh:
#13 0.784 /bin/sh: 1: /tmp/fetch_binaries.sh: Permission denied

I am not seeing this issue , nor am I hitting it on the Docker Hub auto-build. Perhaps this is better if it's fixed within your environment ?


PLAT-124534: Support new RLT scroller coordinate of Chrome 85

Enact-DCO-1.0-Signed-off-by: Jeonghee Ahn<EMAIL_ADDRESS>Checklist

[x] I have read and understand the contribution guide

[x] A CHANGELOG entry is included

[x] At least one test case is included for this feature or bug fix

[ ] Documentation was added or is not needed

[ ] This is an API breaking change

Issue Resolved / Feature Added
ScrollThumb in horizontalScrollbar is located abnormal position when clicking scrolltrack  with RTL.
Resolution
Support new RLT scroller coordinate of Chrome 85 (https://www.chromestatus.com/feature/5759578031521792)

Horizontal (or vertical) scroll position will be zero at its initial position and negative when scrolled leftward (or upward).

Additional Considerations
Links
PLAT-124534
Comments

I changed the merge target to release/3.4.10.


Tailwind completions will not work on .jsx files with the JavaScript syntax type in Nova 10

Ever since Panic removed the JSX syntax styling from Nova 10, the extension will no longer offer completions. It will work if the file extension is changed to .tsx or if the TSX syntax is chosen for .js or .jsx files.

I just pushed an update that should hopefully fix this issue. Please let me know if the problem continues.

Great! No worries. Thanks for letting me know.


Fire Lookout should display the date/time used to compute fire behavior

The date/time used for the computed fire behavior must be displayed to ensure the correctness and relevancy to the situation.

Display in the callout
Display in the info panel

Fixed callout
Added the date and time (from sunlight var) used for the fire behavior calculation.
See commit a3146bba6abb34b1b471238cd22af8a1b8002e6a
Will also date/time add to info panel during its evolution.


Fixing keys for code blocks & lists

Hello @rexxars. Just fixing keys for CodeBlock and List.

Working this in as part of 4.0.1


New World template - Contact form

MW 2.3.1
New World template 5.5

It is not possible to translate "Security Code".

If we have a multilanguage site, there is a problem with the Custom Fields titles: if we translate them to one of the language page, this translation appears in the other language page.

thanks for report, we will take a look

Hello, would you post a screenshot, because that word "Security code" is wrapped in the translation function.

I have two languages and it works for both of them (captcha with numbers)..


Video demostration for c# and angular pls

Video demostration for c# and angular pls

Hi, I am currently trying various PoC, focusing on Java, Kotlin, JavaScript, and TypeScript. However, we can support other languages, so hopefully, we can deploy it.

Can u share a video with any of that language pls

What do you want for the video? Want to know how to use it?

Yes pls
Is for build a good documentation from my side and PR with you if is good for u


One test is currently failing - Failure/Error<EMAIL_ADDRESS>mx: true)).to be_falsey expected: falsey value got: true

with vaild_email 0.1.3
Failures:

  1) ValidateEmail.valid? when mx: true option passed returns false when mx record doesn't exist
     Failure/Error<EMAIL_ADDRESS>mx: true)).to be_falsey
       expected: falsey value
            got: true
     # ./spec/validate_email_spec.rb:23:in `block (4 levels) in <top (required)>'

Finished in 5.3 seconds
105 examples, 1 failure

Failed examples:

rspec ./spec/validate_email_spec.rb:22 # ValidateEmail.valid? when mx: true option passed returns false when mx record doesn't exist
/usr/bin/ruby2.7 -S rspec spec/email_validator_spec.rb spec/extensions_validator_spec.rb spec/validate_email_spec.rb failed

ok fixed by
https://github.com/hallelujah/valid_email/commit/50dc7bdcfc49091065354cf8df0d563de5bcaf26


Add base_superset_client & documentation

Summary of Changes
This PR addresses https://github.com/lyft/amundsenfrontendlibrary/issues/69:

Created a base_superset_preview_client as a starting point for using Superset as the provider for Amundsen's data preview feature.
Implemented an example_superset_preview_client. Note that this is purelu example for getting data from a default table in an instance of Superset running on localhost with security/auth features disabled. It will not work out-of-the-box in production.
Updated the parameters for the data preview feature to include the database. The request to Superset's sql_json endpoint requires a database_id, so we pass the database name for the client to incorporate logic for the potential use case of querying different databases.

Tests

Added tests/unit/base/test_superset_preview_client.py to fully cover the testable logic in that file.
Unrelated cleanup: Modified some assertions in test/unit/api/search/test_v0.py to use a config value for comparison instead of the hardcoded equivalent.

Documentation

Added doc to explain how to approach the implementation of base_superset_preview_client: https://github.com/lyft/amundsenfrontendlibrary/blob/fec747b9aa73cddd79ed533dc1cfd3932d5ef21f/docs/examples/superset_preview_client.md

CheckList
Make sure you have checked all steps below to ensure a timely review.

[x] PR title addresses the issue accurately and concisely. Example: "Updates the version of Flask to v1.0.2"

In case you are adding a dependency, check if the license complies with the ASF 3rd Party License Policy.

[x] PR includes a summary of changes, including screenshots of any UI changes.
[x] PR adds unit tests, updates existing unit tests, OR documents why no test additions or modifications are needed.
[x] In case of new functionality, my PR adds documentation that describes how to use it.

All the public python functions and the classes in the PR contain docstrings that explain what it does

[x] PR passes all tests documented in the developer guide
[x] I have squashed multiple commits if they address the same issue. In addition, my commits follow the guidelines from "How to write a good git commit message"

Codecov Report

Merging #159 into master will increase coverage by 0.15%.
The diff coverage is 50.84%.

@@            Coverage Diff             @@
##           master     #159      +/-   ##
==========================================
+ Coverage   53.13%   53.28%   +0.15%
==========================================
  Files         106      108       +2
  Lines        2650     2708      +58
  Branches      273      276       +3
==========================================
+ Hits         1408     1443      +35
- Misses       1213     1236      +23
  Partials       29       29

Impacted Files
Coverage Δ

...n/base/examples/example_superset_preview_client.py
0% <0%> (ø)

...ication/static/js/components/TableDetail/index.tsx
0% <0%> (ø)
:arrow_up:

...n_application/base/base_superset_preview_client.py
100% <100%> (ø)

amundsen_application/models/preview_data.py
100% <0%> (+27.77%)
:arrow_up:

Continue to review full report at Codecov.

Legend - Click here to learn more
Δ = absolute <relative> (impact), ø = not affected, ? = missing data
Powered by Codecov. Last update b7c94d5...fec747b. Read the comment docs.

cc @verdan @bolkedebruin @jornh

cc @verdan
Here's what we have in the works so far.


A question about pretrain weights

Thanks for your work. My questions is Did you use the vit pretrain weights? In your code it seems that you use the adabins vit pretrain weights.

Thanks for your work. My questions is Did you use the vit pretrain weights? In your code it seems that you use the adabins vit pretrain weights.

No

Thanks for your timely response


ValueReference is only unique within in a base class

I thought a  valueReference was a unique identifier to scalarVariable (or a list of scalarVariable that are aliases). But it seems you can have the same valueReference for a integer/real/boolean/string/enumeration.
That means the getByValueReference function is wrong, as it will return the first occurence.

Seems I never implemented a function for getting a scalar_variable using a value_reference so this is a non-issue.


Fixed typo in tarFileName

Fixes #59

Forgot one last thing. Can you please change the base branch from master to develop?


add hint for using constraint file to prevent unwanted updates

I've found using a constraints.txt file useful for locking the version for packages that I don't want upgraded even when there are new versions.
I think it would be useful to document that "feature" in the README.
(however, it might even be useful to add an option (e.g. pip-review --constraint FILE ...) to specify constraints directly rather than relying indirectly on the behaviour of pip install ...)

I'm OK with merging this, but please move it further down to not break the overview of pip-review's own CLI. I suggest inserting it after Run ``pip-review -h`` for a complete overview of the options.
Honestly, if you have specific packages that you want to protect against updates beyond some version, you're probably better off using pip-tools with a requirements.in.

Thanks - I've moved the section as requested.
I'm not familiar with pip-tools and requirements.in - I'll take a look :)


Document what checks do

Need to say what the checks are that this thingy does.

Made these changes. Thanks, Billy!


Documentation

Describe the solution you'd like
Document all code with access level internal or higher, except declarations made for protocol conformance or overriding subclasses. This allows developers to understand the intention and function of the public interface of types.

Basically document all the functions

Additional context
This is the conform the the best practices described here

Hi Mikaela! ~ Could I get assigned to this issue? I'd like to try. :]

Will do! Sorry I got slammed with take-home assignments and interviews. I'm gonna work start working on the issue this weekend.

If we want to use DocC: https://www.raywenderlich.com/34919511-docc-tutorial-for-swift-getting-started

I would like to contribute by documenting the functions. Could you please assign it to me ?

I'd like to help out with this if you still need it

@ankurwasnik is assigned this issue right now, but if they don't get to it in the next 3 days, go ahead!
@ankurwasnik let me know if you're still working on this
@helloITdepartment you can always find a different issue to work on :)

@ankurwasnik how's it going working on this issue? Do you have any questions? Do you think you'll complete it by the end of Hacktoberfest?

I think I will complete this before due.
On Tue, Oct 25, 2022 at 7:09 PM Mikaela Caron @.***>
wrote:

@ankurwasnik https://github.com/ankurwasnik how's it going working on
this issue? Do you have any questions? Do you think you'll complete it by
the end of Hacktoberfest?
—
Reply to this email directly, view it on GitHub
https://github.com/mikaelacaron/brain-marks/issues/80#issuecomment-1290579600,
or unsubscribe
https://github.com/notifications/unsubscribe-auth/AQIAWF33FMAEC3O4DMNQUTLWE7PJTANCNFSM5F4EK7RQ
.
You are receiving this because you were mentioned.Message ID:
@.***>

do we have to create a new file for all documentation or just add multi-line comments above each function ?

@ankurwasnik you should create multi-line comments, as described here

@mikaelacaron can I get this issue I want to contribute please

@mikaelacaron can I get this issue I want to contribute please

@dcode333 This project isn't active anymore. I can't maintain it because of changes to the Twitter API

@mikaelacaron I just want to make my first contribution as I have an assignment about it can you help me make my first contribution?? Please

@dcode333 Does your assignment require that I merge it?
If not, you're more than welcome to make a PR, but I won't be merging it

@mikaelacaron The main thing is to get it merged..You can't help me in this regard??

@dcode333 No not for this issue, there's too many changes, and I don't have time to look at it, and I don't know what your timeframe is.
You could try this repo IceCubesApp that is currently being developed. I won't have another open source project to be worked on, until Hacktoberfest this October


Add "*" support for log sanitizer

.NET supports it, Java does not.
Do we want to have it?
Also, we may want to check, if .NET supports it only for HTTP headers, or for the query params as well. Generally, if it is fine in one place, it should be ok in another.
Reasons against: security risks, leaking of Authentication headers.
Once we add it, it is a breaking change to remove the support.

PR #3735 has this feature implemented, but do we want it? If yes, the PR can be resurrected.


fix extract message script to adapt multi site feature and clean up l10n constants

Description
As we implement multi-site feature, we move the l10n config from package json to pwa-kit.config.json. As a result,
some commands for translations are not working. Previously, these commands use $npm_* variables to allow us dynamically extract messages to a value set inside package lock json.
As we move away from that, we need to come up with an external script that would allow us to the similar job for multi-site. It is likely we need to extract and compile default messages into different files. (e.g en-GB.json for RefArchGlobal site and en-US.json for RefArch site).
That is when localesToExtractMessages comes in.  This field will define locales that need to be extracted messages to.

Types of Changes

[ ] Bug fix (non-breaking change that fixes an issue)
[ ] New feature (non-breaking change that adds functionality)
[ ] Documentation update
[ ] Breaking change (could cause existing functionality to not work as expected)
[ ] Other changes (non-breaking changes that does not fit any of the above)

Breaking changes include:

Removing a public function or component or prop
Adding a required argument to a function
Changing the data type of a function parameter or return value
Adding a new peer dependency to package.json

Changes

(change1)

How to Test-Drive This PR

delete en-GB.json and en-US.json
run npm run extract-default-translations
en-GB.json and en-US.json should be created and have all the default messages from the project

Checklists

General

[ ] Changes are covered by test cases
[ ] CHANGELOG.md updated with a short description of changes (not required for documentation updates)

Accessibility Compliance
You must check off all items in one of the follow two lists:

[ ] There are no changes to UI

or...

[ ] Changes were tested with a Screen Reader (iOS VoiceOver or Android Talkback) and had no issues
[ ] Changes comply with WCAG 2.0 guidelines levels A and AA
[ ] Changes to common UI patterns and interactions comply with WAI-ARIA best practices

Localization

[ ] Changes include a UI text update in the Retail React App (which requires translation)

@alexvuong I think what you've done here makes great sense. An npm script would not be able to access the new config file, since it's not in its scope. So I would also make a node js script like what you did here.
However, I don't think it's right to extract messages in this manner: doing it for every "default locale" in a site. There is a difference in what a default locale means for react-intl vs Business Manager (BM):

For react-intl, the default locale is like a global value. Default locale means whatever language the default messages are written in. There will only be 1 set of default messages, and they're currently written in English.
On the other hand, in BM, each site may have a different default locale. Thus, in our centralized config, we have multiple defaultLocale values under sites.

So what should we do then? I'd propose the following name changes:

Use “default site locale” instead. For a multisite project, it will be a per-site setting ← this aligns with the default-site-locale concept in BM.
Use “locale of default messages” for react-intl (and it will be a global setting). We still need something for react-intl because otherwise, it can’t tell the locale that the default messages (translations) are written in.

After having a chat with @bendvc and @vmarta, we've decided to not have an external script. Instead, it makes more sense to have a default message file (we chose to go with en-US.json) that is generated by the react-intl extract command for a project. The other files are considered "translated files" which have to be created/translated manually.


Obstacle Avoidance prearm checks and log health status

This PR is an incremental piece of #11550 and substitutes #11456. Adds Obstacle Avoidance to the prearm checks.
If Obstacle Avoidance system is enabled (COM_OBS_AVOID set to 1) then arming will be temporary denied as long as OA is not up and running.
Moreover the status of OA is now logged in the vehicle_status_flags message:

Topic avoidance_system_required: is set to 1 if avoidance system is enabled, 0 if not.
Topic avoidance_system_valid: is set to 1 when avoidance system is up and running, 0 when avoidance system dies.

Eventually another parameter has been added:

COM_ONB_BOOT_T: Allows to specify the timeout time for an onboard controller to bootup and start avoidance. Default set to 10s. After 3 times this timeout has occurred a mavlink message saying "Avoidance not responding. Try reboot vehicle." will happear.

Test data / coverage
Tested in SITL with upstream avoidance and bench tested on a vehicle.
Example of the logged signal when avoidance is lost and regained:

@bkueng @mrivi FYI

Fixed CI failing due to unused variable here 99bd6efc257f9ddca6f478b5625a7c5c5d5ad2d7.
FYI @julianoes


Change FunctionSignature returnType to std::optional to support the return type varied with config

Description
In spark functions, there are many functions whose return datatype are computed by input type and varied with config.
For current case, we always implement as SpecialForm, such as decimal_round, make_decimal.
But it has several shortages:

The name must be unique, so the function name for other types is add, but it should be decimal_add;
The implementation is different and more complex than other common vector functions;
The aggregate function does not have corresponding SpecialForm;

Why we should make returnType optional?

The function identity should only contains name and input types

auto functionWithMetadata = getVectorFunctionWithMetadata(
           call->name(),
           inputTypes,
           getConstantInputs(compiledInputs),
           config))

auto simpleFunctionEntry =
           simpleFunctions().resolveFunction(call->name(), inputTypes)) {

The return type is only used in test code, we can construct CallTypedExpr directly in test code and call evaluate to test.;
For aggregate function, we can also construct CallTypedExpr  and set

core::AggregationNode::Aggregate agg;

    agg.call = std::dynamic_pointer_cast<const core::CallTypedExpr>(
        inferTypes(untypedExpr.expr));

The function with simple result type can still use initial logic.

https://github.com/facebookincubator/velox/pull/10383

What do you think? @mbasmanova @rui-mo @liujiayi771

@jinchengchenghh It is a bit difficult to understand this issue. Would you illustrate the points you are making with detailed examples?

@jinchengchenghh Your point is that in some functions, the output is determined by the input, and it is not possible to accurately represent the result type in the signature. I also encountered situations in decimal agg where the result type couldn't be accurately expressed, and using UNKNOWN would lead to not finding the corresponding agg function.

What's your commits and what error do you meet? Looks like Agg function only consider the function name to find the Agg function. @liujiayi771
const AggregateFunctionEntry* FOLLY_NULLABLE
getAggregateFunctionEntry(const std::string& name);

https://stackoverflow.com/questions/2322736/what-is-the-difference-between-function-declaration-and-signature
A function declaration is the prototype for a function (or it can come from the function definition if no prototype has been seen by the compiler at that point) - it includes the return type, the name of the function and the types of the parameters (optionally in C).
A function signature is the parts of the function declaration that the compiler uses to perform overload resolution. Since multiple functions might have the same name (ie., they're overloaded), the compiler needs a way to determine which of several possible functions with a particular name a function call should resolve to. The signature is what the compiler considers in that overload resolution. Specifically, the standard defines 'signature' as:
the information about a function that participates in overload resolution: the types of its parameters and, if the function is a class member, the cv-qualifiers (if any) on the function itself and the class in which the member function is declared.
Note that the return type is not part of the function signature. As the standard says in a footnote, "Function signatures do not include return type, because that does not participate in overload resolution".

I draft a PR to solve this issue, https://github.com/facebookincubator/velox/pull/10487
This PR https://github.com/facebookincubator/velox/pull/10383/ can also benefits from this solution.
Can you help to take a look? And let me known if we should do this. @mbasmanova

@jinchengchenghh Before proceeding with the changes, would you please explain the issue with detailed examples? See https://github.com/facebookincubator/velox/issues/10467#issuecomment-2228611788

If I remember it correctly, there were some cases among aggregate functions that different intermediate argument types produces the same return type. See avg as an example.
And given that intermediate types are identified as input types while resolving, it's actually a case in Velox that return type has to be known for looking up the correct function.
I'm not sure but if aggregate function is the only reason that return type is needed during resolving, I would suggest to do some refactors against aggregate functions' resolution procedure to avoid using intermediate type as input type. Speaking of SQL, when a function call is being planned, query planner should always derive its return type (and intermediate types if it's a aggregate function) using the data types of arguments. So in theory Velox could follow the same principle to find out the right function implementation without requiring for extra information.

@zhztheplayer I also believe that the agg func should be resolved based on the input type rather than the intermediate type. There is still one issue with Spark decimal avg that remains unresolved, which is that we cannot infer the result type through the intermediate type.

In Spark decimal avg, when the input type is DECIMAL(p, s), the intermediate data's sum type is DECIMAL(p + 10, s), and the final returned average type is DECIMAL(p + 4, s + 4). For intermediate type DECIMAL(p + 10, s), it is possible that when p + 10 exceeds 38, we can't calculate the resultType through the intermediateType anymore. However, both can be determined by the raw input type.

For some decimal functions like round decimal, the result type is determined by input argument value, so it is registered as SpecialForm before.
For decimal arithmetic functions, the result type is determined by runtime config.
Return type is not used to look up functions in resolving for vector functions, it is only used to evaluate string such as round(decimalVal, scale)  to construct CallTypedExpr in test cases.  If test the CallTypedExpr directly, we don't need the resultType in function signature.
And it is confused there are two ways to compute resultType, one is signature to parse, one is code.
https://github.com/facebookincubator/velox/blob/main/velox/functions/sparksql/DecimalArithmetic.cpp#L634
https://github.com/facebookincubator/velox/blob/main/velox/functions/sparksql/DecimalArithmetic.cpp#L415
https://github.com/facebookincubator/velox/pull/10487#issuecomment-2235206986

@jinchengchenghh
In SQL, there are functions and special forms.
A function has a name, a list of argument types and a return type. There can be multiple functions with the same name and different number or types of arguments. The return type of a function can be fully resolved from the list of argument types. It is helpful to support "static" return type resolution and not require instantiating executable functions. For example, one can register a function in Velox, extract its signature from Velox registry, pass it to SQL planner / analyzer and enable queries that use this function without having that function defined within SQL planner / analyzer itself (e.g. one can have C++-only functions that are not defined in Spark Scala or Presto Java code but can be used with these engines). Type resolution also allows writing standalone tests in Velox that use complex expressions and query plans. See PlanBuilder APIs that take SQL strings. Constructing typed expression trees by hand doesn't scale. Notice that Fuzzer also uses function registry to automatically construct valid expression trees. This would not be possible if function registry didn't include the return types.
To evaluate a function, the engine first evaluates all inputs, then invokes the function.
Special forms are similar to functions, but they allow for more flexibility in type resolution or execution. Planner / analyzer needs to know about all special forms as these often have different syntax and do not support "static" type resolution.
Return type for a special form may not be resolvable from just the list of argument types. For example, return type for CAST needs to be specified explicitly. Both CAST(integer as varchar) and CAST(integer as double) take a single argument of type integer, but have different return types: varchar vs. double. Another example, is that return type for round(expr, targetScale) Spark function depends on the value of the second argument, not just its type.
In addition, special forms may not evaluate all the inputs to produce a result. For example, COALESCE is a special form because it evaluates arguments one at a time and once it found an argument that evaluates to non-NULL it returns without evaluating the rest of the arguments. IF is similar. If 'condition' evaluates to true, only 'then' argument is evaluated.
Velox supports both functions and special forms. Functions are required to provide a way to statically resolve return type from input types. Special forms do not have that requirement and they resolve return types dynamically at runtime.

the result type is determined by runtime config.

This case means that there are 2 different functions and config decides which one is used in a given setup. The API to register functions (velox::functions::sparksql::registerFunctions) can take a "config" and use it to decide which function to register. Alternatively, the register API may register 2 functions with different names and plan converter can map the function to one or the other based on config.

And it is confused there are two ways to compute resultType, one is signature to parse, one is code.

FYI, we have extended Simple Function API to support functions with decimal inputs and results and re-implemented Presto functions to use it. This makes it a lot simpler. It might be helpful to do the same for Spark functions.
https://github.com/facebookincubator/velox/pull/9096
CC: @rui-mo

In Gluten, we will not generate QueryConfig when register functions.
Can I add a public function void registerFunctions(const std::string& prefix, core::QueryConfig& config) to register the function by config,
And register the functions with default config in registerFunctions(const std::string& prefix).
void registerFunctions(const std::string& prefix);

void registerFunctions(const std::string& prefix, core::QueryConfig& config);

SimpleFunction cannot get resultPrecision and resultScale, I need it in computation process.
https://github.com/facebookincubator/velox/blob/main/velox/functions/sparksql/DecimalArithmetic.cpp#L380
Do you mind changing it to SpecialForm?

@jinchengchenghh I suggest to change the existing registerFunctions to add a new non-optional parameter that specifies the config for registration. This parameter should be a new struct, not core::QueryConfig, and it should contain only values / flags that influence registration. Something like this:
void registerFunctions(const std::string& prefix, const SparkFunctionRegistrationConfig& config);

SparkFunctionRegistrationConfig name isn't great. We can iterate on it during code review.

SimpleFunction cannot get resultPrecision and resultScale, I need it in computation process.

I'm not sure I understand this question. Please, take a look at Presto functions implementation and provide more details about the problem you are facing if you still have questions.
CC: @rui-mo

Thanks for your explain.
SparkFunctionRegistrationConfig is good.
Preto function is different with Spark function, I have read the Presto functions, it used simple function to implement, but for Spark function, we need result scale, for example
 r = reduceScale(
            TResult(aRescaled + bRescaled), std::max(aScale, bScale) - rScale)

https://github.com/facebookincubator/velox/blob/main/velox/functions/sparksql/DecimalArithmetic.cpp#L380

I can also change it to simple function, compute the result precision and result scale by input types, but this problem still exists.

And it is confused there are two ways to compute resultType, one is signature to parse, one is code.

I tried to change it to simple function and use config to register. but the overwrite logic has a problem.
I register all the functions with allowPrecisionLoss true in SparkFunctionBaseTest, and in a single test, I register allowPrecisionLoss false to try to overwrite the last function.
When I register allowPrecisionLoss false, the FunctionSignature std::unordered_map<std::string, SignatureVariable> variables is different, so we cannot overwrite the previous functions.
The SignatureMap includes
https://github.com/facebookincubator/velox/blob/main/velox/expression/SimpleFunctionRegistry.cpp#L43
I try to print the function signature by
for (auto& [key, value] : signatureMap) {
      std::cout << "signature " << key.toString() << std::endl;
      std::cout << "signature variables size" << key.variables().size()
                << std::endl;
      for (auto& [name, variable] : key.variables()) {
        std::cout << "variable name " << name << " variable constraints"
                  << variable.constraint() << std::endl;
      }
    }

    std::cout << "current signature" << metadata->signature()->toString()
              << std::endl;
    for (auto& [name, variable] : metadata->signature()->variables()) {
      std::cout << "variable name " << name << " variable constraints"
                << variable.constraint() << std::endl;
    }

The print result is
signature variables size6
variable name i7 variable constraints(i1 + i2 + 1) <= 38 ? (i5 + i6) : max((i5 + i6) - (i1 + i2 + 1) + 38, min((i5 + i6), 6))
variable name i6 variable constraints
variable name i5 variable constraints
variable name i3 variable constraintsmin(38, i1 + i2 + 1)
variable name i2 variable constraints
variable name i1 variable constraints
current signature(decimal(i1,i5),decimal(i2,i6)) -> decimal(i3,i7)
variable name i7 variable constraints(i5 + i6) <= 38 ? (i5 + i6) : 38
variable name i6 variable constraints
variable name i5 variable constraints
variable name i3 variable constraintsmin(38, i1 + i2 + 1)
variable name i2 variable constraints
variable name i1 variable constraints

It confirms the signature is different, so we have two FunctionEntry in FunctionMap.
When we try to compile the expressions,
 auto simpleFunctionEntry =
            simpleFunctions().resolveFunction(call->name(), inputTypes)) {

We will get a random one FunctionEntry from FunctionEntry with precision loss and without precision loss.
The solution is:

We don't allow register decimal functions with same name and input types with different result type at session level, user who register it should guarantee this.
Change the decimal arithmetic functions to SpecialForm, then we could use QueryConfig to control it.

What do you think? @mbasmanova
CC @rui-mo

The problem occurs because we register the function considering result type for key FunctionSignature in the map,

@jinchengchenghh It seems a bug in the function registry. It should only consider name and input types and not allow registering functions that differ only in result type. It would be nice to create a separate GitHub issue about this and fix it. CC: @kagamiori @kgpai @bikramSingh91

There is still a concern, the core::QueryConfig is used to construct the function like Addtion while SparkFunctionRegistrationConfig is used to register it, this config for allowPrecisionLoss have the same semantics, the user should register the right SparkFunctionRegistrationConfig and right core::QueryConfig at the same time.

We should not configure same behavior in 2 different places. From what I understand so far, allowPrecisionLoss should be defined only in SparkFunctionRegistrationConfig, not in core::QueryConfig.

I register all the functions with allowPrecisionLoss true in SparkFunctionBaseTest, and in a single test, I register allowPrecisionLoss false to try to overwrite the last function.

To workaround the bug in the registry, you may register functions in the test with different prefixes.

Because decimal allow precision loss mode is a session config, and we register functions before the session created.
So can we choose the second way which suggests to register functions with different name? @mbasmanova

Alternatively, the register API may register 2 functions with different names and plan converter can map the function to one or the other based on config.

And we will not need to overwrite function in the session level.

This case means that there are 2 different functions and config decides which one is used in a given setup. The API to register functions (velox::functions::sparksql::registerFunctions) can take a "config" and use it to decide which function to register. Alternatively, the register API may register 2 functions with different names and plan converter can map the function to one or the other based on config.

We may have to take the second option and select the used function at runtime since we need to adapt to user-specified session configuration which determines whether to allow precision loss. Thanks!


Handle failure to open a file link

Print output of the open link process as an error.

To print output as an error need to properly concatenate stdout and stderr of the process. That involves buffering text until line breaks arrive. Required code already exists but it is tied to executions.
Need to do a refactor: untie processes from executions: there is a lot of execution processing code that expects that if there is a process component - there is always an execution component alongside. Need to change that to be able to just launch processes without executions.


Convert OPA to use cloud native packaging

For 2.5 we need to package OPA following the cloud native packaging process

from Prachi:

We should validate install/uninstall and also the create constrainttemplates/constraints and that the constraints applied work.

From Steven:

We should validate that rancher-gatekeeper installs/uninstalls rancher-gatekeeper-crd, and the CRDs are cleaned up on uninstall.

Uninstall is blocked by #28097

Dashboard issues:
https://github.com/rancher/dashboard/issues/1016
https://github.com/rancher/dashboard/issues/1011

Currently blocked by:
https://github.com/rancher/dashboard/issues/1145
Additional Dashboard issues:
https://github.com/rancher/dashboard/issues/1136
https://github.com/rancher/dashboard/issues/1104
https://github.com/rancher/dashboard/issues/1100
https://github.com/rancher/dashboard/issues/1099

Tested with Rancher server rancher\rancher:master-head version 76c26fb. OPA is functionally available.
OPA Gatekeeper Version rancher-gatekeeper:v3.1.0-rc.1
Logged bugs to be tracked separately:
https://github.com/rancher/dashboard/issues/1194
https://github.com/rancher/dashboard/issues/1200


use pipenv and cleanup templates

the use of pipenv and an .env file seems more convenient.  also went through the templates and tidied them up a little.

Thanks for the PR. I like the changes. However, I am concerned that this ties the project to pipenv, which not everyone uses. Can you add the requirements file back in and also updated the readme, adding back in instructions for those not wanting to use pipenv?

totally agree with not tieing people in with a tool they may not use 👍.  I've added back the information to the readme and returned the requirments.txt.


No subtitle support?

From what I checked, there's subtitle preset support but not actually subtitle hard coding support.

Woops, nevermind, found what I was looking for at
FFmpegBuilder


Discontinuity in the ET potential

We found that there is a discontinuity in the torchmd-net ET potential when atoms cross the cutoff distance. I assume it is not the intended behavior of the potential. We noticed that in larger calculations with our own models, but it can easily be demonstrated on a system with two atoms using a model from the SPICE-models repository (https://github.com/openmm/spice-models). Therefore, the issue is not specific to the models we are developing.
The following code (using torchmd-net 0.8.1 installed with conda, the results are the same when I upgraded to 0.11.0) reproduces the issue, there is a discontinuity of about 3.6 kJ/mol at the distance of 10A, which is the cutoff used in this model. In our models with cutoff 5 A, similar step occurs at that distance. In the intermolecular potential of larger molecules, multiple steps can be found where the individual atoms cross the cutoff.
The code produces a warning at the cutoff distance saying that gradients are not calculated, but that is not the problem - it is the change in energy.
import sys
import torch
from torchmdnet.models.model import load_model

# Load the model
# As an example, model from the spice-models repository is used:
# https://github.com/openmm/spice-models/blob/main/five-et/model1.ckpt
model = load_model("model1.ckpt", derivative=True)

# Types - two atoms of selected elements, H and O
types = torch.tensor([10, 21], dtype=torch.long)

# Iterate distances from 9.9 to 10.1 A
dist = 9.9
step = 0.01
while dist < 10.1:
    # Construct the geometry
    pos = torch.tensor([[0,0,0],[dist,0,0]], dtype=torch.float32)
    # Compute energy and forces
    energy, forces = model.forward(types, pos)
    # Print distance and energy
    print("dist = %.3f   energy = %.5f" % (dist, energy))
    dist += step

Thanks for the wonderful reproducer!
We can reproduce it and are currently investigating.


bnet peer sent bad block

I start bnet and p2p configures in config.ini,  when I start to sync data, got following error:
bnet_plugin.cpp:510           on_bad_block         ] peer sent bad block #10330183 009da047d0d037aea2c808d4ea7be750f1db707ae2ae8c9954b2b3c6f7a022e5, disconnect\n","stream":"stderr","time":"2018-08-10T00:13:07.64839037Z"}

Would you share your config?

I will set the p2p and bnet for same mahcin in the config.ini, is this the reason?
# the endpoint upon which to listen for incoming connections (eosio::bnet_plugin)
bnet-endpoint = <IP_ADDRESS>:3389
bnet_threads = 4

bnet-connect = <IP_ADDRESS>:3389
bnet-connect = <IP_ADDRESS>:3389

# the number of threads to use to process network messages (eosio::bnet_plugin)
# bnet-threads =

# remote endpoint of other node to connect to; Use multiple bnet-connect options as needed to compose a network (eosio::bnet_plugin)
# bnet-connect =

# this peer will request no pending transactions from other nodes (eosio::bnet_plugin)
bnet-no-trx = false

# the location of the blocks directory (absolute path or relative to application data dir) (eosio::chain_plugin)
blocks-dir = "blocks"

# Pairs of [BLOCK_NUM,BLOCK_ID] that should be enforced as checkpoints. (eosio::chain_plugin)
# checkpoint =

# Override default WASM runtime (eosio::chain_plugin)
# wasm-runtime =

# Maximum size (in MB) of the chain state database (eosio::chain_plugin)
chain-state-db-size-mb = 65536

# Maximum size (in MB) of the reversible blocks database (eosio::chain_plugin)
reversible-blocks-db-size-mb = 340

# print contract's output to console (eosio::chain_plugin)
contracts-console = false

# Account added to actor whitelist (may specify multiple times) (eosio::chain_plugin)
# actor-whitelist =

# Account added to actor blacklist (may specify multiple times) (eosio::chain_plugin)
# actor-blacklist =

# Contract account added to contract whitelist (may specify multiple times) (eosio::chain_plugin)
# contract-whitelist =

# Contract account added to contract blacklist (may specify multiple times) (eosio::chain_plugin)
# contract-blacklist =

# Track actions which match receiver:action:actor. Actor may be blank to include all. Receiver and Action may not be blank. (eosio::history_plugin)
# filter-on =

# PEM encoded trusted root certificate (or path to file containing one) used to validate any TLS connections made.  (may specify multiple times)
#  (eosio::http_client_plugin)
# https-client-root-cert =

# true: validate that the peer certificates are valid and trusted, false: ignore cert errors (eosio::http_client_plugin)
https-client-validate-peers = 0
# The local IP and port to listen for incoming http connections; set blank to disable. (eosio::http_plugin)
http-server-address = <IP_ADDRESS>:80

# The local IP and port to listen for incoming https connections; leave blank to disable. (eosio::http_plugin)
# https-server-address =

# Filename with the certificate chain to present on https connections. PEM format. Required for https. (eosio::http_plugin)
# https-certificate-chain-file =

# Filename with https private key in PEM format. Required for https (eosio::http_plugin)
# https-private-key-file =

# Specify the Access-Control-Allow-Origin to be returned on each request. (eosio::http_plugin)
access-control-allow-origin = *

# Specify the Access-Control-Allow-Headers to be returned on each request. (eosio::http_plugin)
# access-control-allow-headers =

# Specify the Access-Control-Max-Age to be returned on each request. (eosio::http_plugin)
# access-control-max-age =

# Specify if Access-Control-Allow-Credentials: true should be returned on each request. (eosio::http_plugin)
access-control-allow-credentials = false
http-validate-host = false
# The actual host:port used to listen for incoming p2p connections. (eosio::net_plugin)
p2p-listen-endpoint = <IP_ADDRESS>:443

# eosfnhkali01
p2p-peer-address = <IP_ADDRESS>:443
# eosfnhkali02
p2p-peer-address = <IP_ADDRESS>:443

# Maximum number of client0nodes from any single IP address (eosio::net_plugin)
p2p-max-nodes-per-host = 10000

# The name supplied to identify this node amongst the peers. (eosio::net_plugin)
agent-name = "XXXX"

# Can be 'any' or 'producers' or 'specified' or 'none'. If 'specified', peer-key must be specified at least once. If only 'producers', peer-key is not required. 'producers' and 'specified' may be combined. (eosio::net_plugin)
allowed-connection = any

# Optional public key of peer allowed to connect.  May be used multiple times. (eosio::net_plugin)
# peer-key =

# Tuple of [PublicKey, WIF private key] (may specify multiple times) (eosio::net_plugin)
# peer-private-key =

# Maximum number of clients from which connections are accepted, use 0 for no limit (eosio::net_plugin)
max-clients = 10000

# number of seconds to wait before cleaning up dead connections (eosio::net_plugin)
connection-cleanup-period = 30

verbose-http-errors = true

# True to require exact match of peer network version. (eosio::net_plugin)
network-version-match = 0

# number of blocks to retrieve in a chunk from any individual peer during synchronization (eosio::net_plugin)
sync-fetch-span = 100

# maximum sizes of transaction or block messages that are sent without first sending a notice (eosio::net_plugin)
max-implicit-request = 1500

# Enable block production, even if the chain is stale. (eosio::producer_plugin)
enable-stale-production = false

# Start this node in a state where production is paused (eosio::producer_plugin)
pause-on-startup = false

# Limits the maximum time (in milliseconds) that is allowed a pushed transaction's code to execute before being considered invalid (eosio::producer_plugin)
max-transaction-time = 30

# Limits the maximum age (in seconds) of the DPOS Irreversible Block for a chain this node will produce blocks on (use negative value to indicate unlimited) (eosio::producer_plugin)
max-irreversible-block-age = -1

# ID of producer controlled by this node (e.g. inita; may specify multiple times) (eosio::producer_plugin)
# producer-name =

# (DEPRECATED - Use signature-provider instead) Tuple of [public key, WIF private key] (may specify multiple times) (eosio::producer_plugin)
# private-key =

# Key=Value pairs in the form <public-key>=<provider-spec>
# Where:
#    <public-key>       is a string form of a vaild EOSIO public key
#
#    <provider-spec>    is a string in the form <provider-type>:<data>
#
#    <provider-type>    is KEY, or KEOSD
#
#    KEY:<data>         is a string form of a valid EOSIO private key which maps to the provided public key
#
#    KEOSD:<data>       is the URL where keosd is available and the approptiate wallet(s) are unlocked (eosio::producer_plugin)
#signature-provider = EOS6MRyAjQq8ud7hVNYcfnVPJqcVpscN5So8BhtHuGYqET5GDW5CV=KEY:5KQwrPbwdL6PhXujxW37FSSQZ1JiwsST4cqQzDeyXtP79zkvFD3

# Limits the maximum time (in milliseconds) that is allowd for sending blocks to a keosd provider for signing (eosio::producer_plugin)
keosd-provider-timeout = 5

# Lag in number of blocks from the head block when selecting the reference block for transactions (-1 means Last Irreversible Block) (eosio::txn_test_gen_plugin)
txn-reference-block-lag = 0

# The path of the wallet files (absolute path or relative to application data dir) (eosio::wallet_plugin)
wallet-dir = "."

# Timeout for unlocked wallet in seconds (default 900 (15 minutes)). Wallets will automatically lock after specified number of seconds of inactivity. Activity is defined as any wallet command e.g. list-wallets. (eosio::wallet_plugin)
unlock-timeout = 900

# eosio key that will be imported automatically when a wallet is created. (eosio::wallet_plugin)
# eosio-key =

# Plugin(s) to enable, may be specified multiple times
# plugin =
plugin = eosio::chain_api_plugin
plugin = eosio::history_api_plugin
plugin = eosio::bnet_plugin
plugin = eosio::http_plugin

It is recommended to use net_plugin (p2p). Can you test with the latest version?  If you still have the problem and wish to discuss further, please post it in https://eosio.stackexchange.com.


TypeError: Cannot read properties of undefined (reading 'find')

This issue occurs when I use the update function. I add two lines and leave all the required fields empty in those two lines. Then, when I click submit, I get an error message saying that the necessary fields are not filled out. Finally, if I delete the second line, an error occurs.
version

nova: 4.26.5
nova-simple-repeatable: 2.2.1

error message
TypeError: Cannot read properties of undefined (reading 'find')
    at Proxy.getValidationKey (http://myserver/nova-api/scripts/simple-repeatable:2:34392)
    at http://myserver/nova-api/scripts/simple-repeatable:2:73351
    at Array.forEach (<anonymous>)
    at s (http://myserver/nova-api/scripts/simple-repeatable:2:73320)
    at Proxy.repeatableValidation (http://myserver/nova-api/scripts/simple-repeatable:2:73424)
    at Ee.run (http://myserver/vendor/nova/vendor.js?id=f249b9bf29d2374b7fa61636323b3851:2:1499936)
    at get value [as value] (http://myserver/vendor/nova/vendor.js?id=f249b9bf29d2374b7fa61636323b3851:2:1508813)
    at Object.get [as repeatableValidation] (http://myserver/vendor/nova/vendor.js?id=f249b9bf29d2374b7fa61636323b3851:2:1531633)
    at http://myserver/nova-api/scripts/simple-repeatable:2:76090
    at ni (http://myserver/vendor/nova/vendor.js?id=f249b9bf29d2374b7fa61636323b3851:2:1527877)

@Tarpsvo @marttinnotta Can confirm we are seeing this too seems to have been caused by the last release.

Thank you for reporting this!
Currently I reverted my incompetent changes back to prior ForemData update (update that causes this). If you by any chance used json method I left it intact (it does nothing) so that it would not create any undefined errors.
In future I will add more thorough test cases with different fields to avoid this kind of situation.
I sincerely apologies for any inconvenience I may have caused.


HTTP Support GELF

Hi,
Is it possible to use HTTP GELF instead of UDP gelf?

@dennusb, you simply have to use the HttpTransport when you declare your handler:
$monolog->pushHandler(new GelfHandler(new Publisher(new HttpTransport(yourserver.com', 12201))));


ignore certain geometry properties

Ad-hoc solution for addressing a common complaint. These few properties won't do anything visual from the Editor. So remove them to clean up the noise on one of the more important components.

I'm not sure if it's good going down that path. What's the criteria to hide properties? There are just a few properties that are noisy and even in that case the fact that show up in the editor makes them discoverable. What about this? Let's make an editable boolean in the property schema. If editable is false the editor still shows the property but grayed out.

Yeah, it's very ad-hoc. These are the only three offending properties at the moment. I think this is okay to polish the initial release and then find a scalable solution later (i.e,., allowing components to configure editor appearance).

Can we make them non editable instead of hiding them? At least you can see the property and it's current value.

The issue was more that they are visible in the first place.
So it's usability (modifying relevant properties that have any actual effect in the Editor) vs. property discoverability (seeing all the properties). I think disabling them would help, so people don't try to modify them and see nothing happen, though it'd be slightly weird to expose non-editable properties in the Editor.
What about https://github.com/aframevr/aframe-editor/issues/31 for property discoverability? Since at least component discoverability is not affected by this.

It deviates the editor from its purpose of teaching you about components. I don't think that seeing those properties is that big of an issue. They're going to be a tiny fraction of them.

Even if those properties are not editable at runtime it can be useful to see their value to diagnose problems. Something could be affecting the appearance of the entities and one of those hidden properties could be the reason. I believe in the hide nothing approach.

I also like the approach of disable them but put everything visible.

Fair enough. I have repurposed the PR to just the refactor changes.

Rebased.


Complex message edit

This function not only lets you edit both embeds and content at once but also allows for completely removing embeds by passing a nil to "embed" key in message edit builder.

Added some better error handling. The above error is because the GetMarshalNil() does not exist in current version of discordgo here. Should be fixed post update.

assume this runs fine


Add first implementation of htcondor collector.

Hey all,
this implements a collector for collecting data from an HTCondor batch system. It uses the pyauditor-client for connecting to an AUDITOR-instance. The collector is currently collecting data at the German tier 1 WLCG site.
Cheers,
Florian

@stefan-k, thanks for the ReviewLight™ 😅 I've moved the docu to the website and changed the Cargo.toml to explicitly state the slurm-collectors so the CI should hopefully become greener again.
I'll have a look at how to add tests for the collector in the CI.
Enjoy your vacation!

Concerning the type annotations, that's certainly true. I've added them (hopefully) everywhere in 23e2820.

Codecov Report

Merging #264 (23e2820) into main (7ce9cde) will increase coverage by 1.26%.
The diff coverage is n/a.

@@            Coverage Diff             @@
##             main     #264      +/-   ##
==========================================
+ Coverage   50.83%   52.09%   +1.26%
==========================================
  Files          41       41
  Lines        3049     3100      +51
==========================================
+ Hits         1550     1615      +65
+ Misses       1499     1485      -14

see 4 files with indirect coverage changes
Help us with your feedback. Take ten seconds to tell us how you rate us. Have a feature suggestion? Share it here.

Hey @rfvc,
I'm just checking in to see if there are any stoppers on your side that you would need help with. Michael told me that you are currently working on the integration tests for this plugin. Just for my overview: Is there anything else missing?
Cheers

Hey @QuantumDancer, @dirksammel, I think I have addressed all requested changes, except the integration tests. I'm still not done with those, as I am having some issues with networking/authentication which I am working on. For keeping track of this I have opened #301
Maybe you guys can re-review and we can merge for the moment?
Cheers


How to install?

Some pointers for newbie like me would help.

Hello there,
Currently you have to open the project in Xcode and build it to run the resulting Diurna.app.
I do not distribute the app yet, as I deem it quite crude, and as of late unmaintained. But that might change in the following weeks 😉