Vibe.d HTTP Request strange behavior - Second attempt to send HTTP request failed

2020-06-25 Thread Voxel via Digitalmars-d-learn
We would like to use vibe.d for a simple backend, but run into 
strange behavior with HTTP request. The backend is simple: it 
receives requests from clients and makes requests for some json 
contents. Now, the code is only a vibe.d basic http server and a 
sample http request from vibe.d example.


Sometimes(very often) we got the error:

"statusMessage":"Second attempt to send HTTP request 
failed.","statusDebugMessage":"object.Exception@../../../.dub/packages/vibe-d-0.8.6/vibe-d/http/vibe/http/client.d(615): Second attempt to send HTTP request failed.\n\n/usr/include/dlang/dmd/std/exception.d:516 pure..."


It starts happening when there is no request for a few seconds. 
The error comes only, when I read the response (res.readJson(); 
or res.bodyReader.readAllUTF8();).


Our simple test case is: start vibe.d server, open a browser. 
Opening our server url makes a http request to our vibe.d server, 
which tries to make a http request to an another server.


I found some related content here: 
https://github.com/vibe-d/vibe.d/issues/2290
And here (second commenter is me): 
https://github.com/vibe-d/vibe.d/issues/2451


We use the latest stable vibe.d(0.8.6), dub and dmd.

We tried several things, but nothing works.



Calling C functions

2020-06-25 Thread Denis via Digitalmars-d-learn

I have a two questions about calling C functions from D.

(1) When passing a D callback to a C function, is there a way to 
write the code without having to prefix the callback declaration 
with "extern(C)"?


It's not a big deal adding the prefix to the D function 
declaration. It just seems odd to me to prefix D code with 
"extern(C)". For example, the following code works:


  extern(C) void cfunc(void function(int));
  extern(C) void dcallback(int x) {...} <-- Why extern(C)?
  cfunc();

Can this be rewritten, dropping the prefix from the second line? 
If not, it would be helpful to know why "extern(C)" is needed 
here too.


(2) Is there a way to restrict the invocation of a linked C 
function to one specific D function?


If the C header is defined in one of the core.stdc libraries, the 
import statement can either be global or inside a specific D 
function -- both work. In contrast, when the C function prototype 
is written directly into the D program (as above), the linker 
complains unless this declaration is made global. If it's 
possible to restrict the scope of the C function to just one D 
function, I'll take advantage.


(I'm using dmd, if that makes a difference.)

Thanks


Re: Iterators in structs

2020-06-25 Thread Paul Backus via Digitalmars-d-learn

On Thursday, 25 June 2020 at 18:47:42 UTC, repr-man wrote:

struct ChunksOf(R)
{
Chunks!R iter;

this(R r, size_t width)
{
this.iter = r.chunks(width);
assert(is(typeof(iter) == Chunks!R));
}
}

This works, only if I change the declaration of x in main() to:

auto x = ChunksOf!(chain(a[], b[]))(chain(a[], b[]), 2);

This requires me to pass the iterator as a template parameter 
and a regular parameter.  Since this is a bit redundant, and I 
wanted to know if there was a better way to do it.


Thanks for the help!


The usual solution is to create a helper function:

ChunksOf!R chunksOf(R)(R r, size_t width)
{
return ChunksOf!R(r, width);
}

The compiler can infer template arguments for function calls, so 
you can call it like this:


auto x = chunksOf(chain(a[], b[]), 2);


Iterators in structs

2020-06-25 Thread repr-man via Digitalmars-d-learn
As an extension of my previous thread 
(https://forum.dlang.org/thread/nupwljahyutnyxdvp...@forum.dlang.org), I wanted to ask about iterators in structs.  I will start with the following code:


void main()
{
int[5] a = [0, 1, 2, 3, 4];
int[5] b = [5, 6, 7, 8, 9];

auto x = ChunksOf(chain(a[], b[]), 2);
}

struct ChunksOf
{
this(R)(R r, size_t width)
{
auto iter = r.chunks(width);
assert(is(typeof(iter) == Chunks!R));
}
}

This code works as expected.  However, if the struct changes to:

struct ChunksOf
{
Chunks!R iter;

this(R)(R r, size_t width)
{
this.iter = r.chunks(width);
assert(is(typeof(iter) == Chunks!R));
}
}

it doesn't compile because R is only in the scope of the 
constructor.  This leads me to change the struct to:


struct ChunksOf(R)
{
Chunks!R iter;

this(R r, size_t width)
{
this.iter = r.chunks(width);
assert(is(typeof(iter) == Chunks!R));
}
}

This works, only if I change the declaration of x in main() to:

auto x = ChunksOf!(chain(a[], b[]))(chain(a[], b[]), 2);

This requires me to pass the iterator as a template parameter and 
a regular parameter.  Since this is a bit redundant, and I wanted 
to know if there was a better way to do it.


Thanks for the help!


Re: Passing iterators into functions

2020-06-25 Thread Mike Parker via Digitalmars-d-learn

On Thursday, 25 June 2020 at 03:35:00 UTC, repr-man wrote:



This seems to have to do with the fact that all iterators 
return their own unique type.  Could someone help me understand 
the reason behind this design and how to remedy my situation?


Ranges conform to well-defined interfaces. Given that the 
algorithms in Phobos are templates and use structs rather than 
classes, this means the interfaces are checked at compile time 
(see the `is*` templates in std.range.primitives [1]). It also 
means that there is no concrete range "type" returned by these 
functions. That's why all of them return `auto` instead of a 
specific type. You never need to know the specific type of a 
range.


Arrays are ranges only because of the free-function 
implementation of the range interfaces in std.range.primitives 
which all take an array as the first argument so that they may be 
called using UFCS in any templated range algorithm.


So when you input an array to a range algorithm, the algorithm 
has no idea it has an array. It just calls R.emtpy, R.front, 
etc., without ever caring what the actual type is. And you can 
chain them because each algorithm wraps the input range with 
custom range type that actually implements the algorithm (in 
e.g., `popFront`--that's also why ranges are lazy), and that's 
what is returned. In a chain of function calls, popFront is 
called on the outermost range, which calls popFront on its 
wrapped range, which calls popFront on its wrapped range, etc. So 
if you append std.array.array to the end of the chain, it will 
kick off execution of the whole chain of calls by making the 
first call to popFront in order to copy the result into a new 
array.


Chapter 6, "Understanding Ranges", from "Learning D" is available 
freely online [2]. You should give it a read.



[1] https://dlang.org/phobos/std_range_primitives.html
[2] https://hub.packtpub.com/understanding-ranges/


Re: Passing iterators into functions

2020-06-25 Thread Ali Çehreli via Digitalmars-d-learn
Collection elements are accessed by ranges in D. Although both iterators 
and ranges fundamentally do the same thing (access elements). More 
accurately, ranges correspond to a pair iterators.


On 6/24/20 8:35 PM, repr-man wrote:

> auto func(R)(R r, size_t width)
> if(isRandomAccessRange!R)
> {
>  return r.chunks(width);
> }
>
> void main()
> {
>  int[5] a = [0, 1, 2, 3, 4];
>  int[5] b = [5, 6, 7, 8, 9];
>  auto x = func!(int[])(chain(a[], b[]), 5);

Is there a reason why you specify the template argument there?

> This seems to have to do with the fact that all iterators return their
> own unique type.

When the element is normally different, there would be no way of using 
one type anyway. This is similar to how vector::iterator is a 
different type from e.g. vector::iterator.


> Could someone help me understand the reason behind
> this design

Andrei Alexandrescu has the following article on D's ranges:

  https://www.informit.com/articles/printerfriendly/1407357

> and how to remedy my situation?

Just don't specify the function template argument and it will work.

Ali