问:
How does the prime numbers example from the Kotlin Coroutines documentation work?
I'm going through the coroutines documentation for Kotlin and was following along pretty well until this example.  I'm having a really difficult time understanding how it's calculating when it finds a prime number, and specifically how the return from the filter function is both being returned and assigned to cur, as well as still producing numbers from the numbersFrom method.

I've added debugging statements to try and follow the various coroutines that are running, but I'm still lost on the logical flow of when it starts new coroutines and receives numbers from others.

https://github.com/Kotlin/kotlinx.coroutines/blob/master/coroutines-guide.md#prime-numbers-with-pipeline

The code:

```<code>fun log(msg: String) = println("[${Thread.currentThread().name}] $msg")

fun main(args: Array<String>) = runBlocking<Unit> {
    var cur = numbersFrom(context, 2)
    for (i in 1..10) {
        val prime = cur.receive()
        println(prime)
        cur = filter(context, cur, prime)
    }
}

fun numbersFrom(context: CoroutineContext, start: Int) = produce<Int>(context) {
       var x = start
    while (true) {
        log("NumbersFrom Send: ${x}")
        send(x++)
    } // infinite stream of integers from start
}

fun filter(context: CoroutineContext, numbers: ReceiveChannel<Int>, prime: Int) = produce<Int>(context) {
    for (x in numbers) {
        log("filter ${x}, prime ${prime}")
        if (x % prime != 0) {
            send(x)
        }
    }
}
</code>```

Outout:

```<code>[main @coroutine#2] NumbersFrom Send: 2
[main @coroutine#2] NumbersFrom Send: 3
2
[main @coroutine#3] filter 3, prime 2
[main @coroutine#2] NumbersFrom Send: 4
[main @coroutine#2] NumbersFrom Send: 5
3
[main @coroutine#3] filter 4, prime 2
[main @coroutine#3] filter 5, prime 2
[main @coroutine#4] filter 5, prime 3
[main @coroutine#2] NumbersFrom Send: 6
[main @coroutine#3] filter 6, prime 2
5
[main @coroutine#2] NumbersFrom Send: 7
[main @coroutine#2] NumbersFrom Send: 8
[main @coroutine#3] filter 7, prime 2
[main @coroutine#3] filter 8, prime 2
[main @coroutine#4] filter 7, prime 3
[main @coroutine#2] NumbersFrom Send: 9
[main @coroutine#2] NumbersFrom Send: 10
[main @coroutine#5] filter 7, prime 5
[main @coroutine#3] filter 9, prime 2
[main @coroutine#3] filter 10, prime 2
7
[main @coroutine#4] filter 9, prime 3
[main @coroutine#2] NumbersFrom Send: 11
[main @coroutine#2] NumbersFrom Send: 12
[main @coroutine#3] filter 11, prime 2
[main @coroutine#3] filter 12, prime 2
[main @coroutine#4] filter 11, prime 3
[main @coroutine#2] NumbersFrom Send: 13
[main @coroutine#2] NumbersFrom Send: 14
[main @coroutine#5] filter 11, prime 5
[main @coroutine#3] filter 13, prime 2
[main @coroutine#3] filter 14, prime 2
[main @coroutine#6] filter 11, prime 7
[main @coroutine#4] filter 13, prime 3
[main @coroutine#2] NumbersFrom Send: 15
[main @coroutine#2] NumbersFrom Send: 16
11
[main @coroutine#5] filter 13, prime 5
[main @coroutine#3] filter 15, prime 2
[main @coroutine#3] filter 16, prime 2
[main @coroutine#6] filter 13, prime 7
[main @coroutine#4] filter 15, prime 3
[main @coroutine#2] NumbersFrom Send: 17
[main @coroutine#2] NumbersFrom Send: 18
[main @coroutine#7] filter 13, prime 11
[main @coroutine#3] filter 17, prime 2
[main @coroutine#3] filter 18, prime 2
13
[main @coroutine#4] filter 17, prime 3
[main @coroutine#2] NumbersFrom Send: 19
[main @coroutine#2] NumbersFrom Send: 20
[main @coroutine#5] filter 17, prime 5
[main @coroutine#3] filter 19, prime 2
[main @coroutine#3] filter 20, prime 2
[main @coroutine#6] filter 17, prime 7
[main @coroutine#4] filter 19, prime 3
[main @coroutine#2] NumbersFrom Send: 21
[main @coroutine#2] NumbersFrom Send: 22
[main @coroutine#7] filter 17, prime 11
[main @coroutine#5] filter 19, prime 5
[main @coroutine#3] filter 21, prime 2
[main @coroutine#3] filter 22, prime 2
[main @coroutine#8] filter 17, prime 13
[main @coroutine#6] filter 19, prime 7
[main @coroutine#4] filter 21, prime 3
[main @coroutine#2] NumbersFrom Send: 23
[main @coroutine#2] NumbersFrom Send: 24
17
[main @coroutine#7] filter 19, prime 11
[main @coroutine#3] filter 23, prime 2
[main @coroutine#3] filter 24, prime 2
[main @coroutine#8] filter 19, prime 13
[main @coroutine#4] filter 23, prime 3
[main @coroutine#2] NumbersFrom Send: 25
[main @coroutine#2] NumbersFrom Send: 26
[main @coroutine#9] filter 19, prime 17
[main @coroutine#5] filter 23, prime 5
[main @coroutine#3] filter 25, prime 2
[main @coroutine#3] filter 26, prime 2
19
[main @coroutine#6] filter 23, prime 7
[main @coroutine#4] filter 25, prime 3
[main @coroutine#2] NumbersFrom Send: 27
[main @coroutine#2] NumbersFrom Send: 28
[main @coroutine#7] filter 23, prime 11
[main @coroutine#5] filter 25, prime 5
[main @coroutine#3] filter 27, prime 2
[main @coroutine#3] filter 28, prime 2
[main @coroutine#8] filter 23, prime 13
[main @coroutine#4] filter 27, prime 3
[main @coroutine#2] NumbersFrom Send: 29
[main @coroutine#2] NumbersFrom Send: 30
[main @coroutine#9] filter 23, prime 17
[main @coroutine#3] filter 29, prime 2
[main @coroutine#3] filter 30, prime 2
[main @coroutine#10] filter 23, prime 19
[main @coroutine#4] filter 29, prime 3
[main @coroutine#2] NumbersFrom Send: 31
[main @coroutine#2] NumbersFrom Send: 32
23
[main @coroutine#5] filter 29, prime 5
[main @coroutine#3] filter 31, prime 2
[main @coroutine#3] filter 32, prime 2
[main @coroutine#6] filter 29, prime 7
[main @coroutine#4] filter 31, prime 3
[main @coroutine#2] NumbersFrom Send: 33
[main @coroutine#2] NumbersFrom Send: 34
[main @coroutine#7] filter 29, prime 11
[main @coroutine#5] filter 31, prime 5
[main @coroutine#3] filter 33, prime 2
[main @coroutine#3] filter 34, prime 2
[main @coroutine#8] filter 29, prime 13
[main @coroutine#6] filter 31, prime 7
[main @coroutine#4] filter 33, prime 3
[main @coroutine#2] NumbersFrom Send: 35
[main @coroutine#2] NumbersFrom Send: 36
[main @coroutine#9] filter 29, prime 17
[main @coroutine#7] filter 31, prime 11
[main @coroutine#3] filter 35, prime 2
[main @coroutine#3] filter 36, prime 2
[main @coroutine#10] filter 29, prime 19
[main @coroutine#8] filter 31, prime 13
[main @coroutine#4] filter 35, prime 3
[main @coroutine#2] NumbersFrom Send: 37
[main @coroutine#2] NumbersFrom Send: 38
[main @coroutine#11] filter 29, prime 23
[main @coroutine#9] filter 31, prime 17
[main @coroutine#5] filter 35, prime 5
[main @coroutine#3] filter 37, prime 2
[main @coroutine#3] filter 38, prime 2
29
[main @coroutine#10] filter 31, prime 19
[main @coroutine#4] filter 37, prime 3
[main @coroutine#2] NumbersFrom Send: 39
</code>```

答:
The point of the example is to implement the Sieve of Eratosthenes. In other words, to find prime numbers by filtering out numbers that can't be prime because of their divisibility. Anything left is a prime.

Let's look at what we have. I'm going to ignore all of the context variables for now, it just makes things easier to talk about.

First, we have a function called numbersFrom, which is just an endless sequence of integers starting at 2 (in this case).

We also have function called filter, which takes in a channel, and a number which is presumably prime. Looking at the return type, we can see that this function returns a new producer. In order to produce results (Ints in this case), the send function can be called. Looking at the body of the function, filter will accept numbers off the channel (via send) and REJECT anything that is evenly divisible by the prime number (by doing nothing).

For example, if the channel produces a 4 and the prime is a 2, that is rejected. On the other hand, if the channel produces a 5 and the prime is a 2, it will send that number along. It should now become obvious that filter does what its name says - read inputs, find the ones it likes, send them along to its output.

Now let's look at the main function. First we create a stream of numbers starting at 2 (what a coincidence, the first prime!) and assign that to cur. So far, so good.

Next, we start a loop. I reduced the 10 to a 3 to make things easier to understand, but essentially that number means how many primes the main method will calculate. If you want the first 100 primes, set it to 100.

In the loop, we take the first number off the numbers list, by calling receive() on cur. This is a suspending function. And as I mentioned above, it will get a 2 as its first prime value.

And now here is the fun part. We take that 2, and use it as the basis for a call to filter, along with cur, which is currently the stream of Ints, and reassign that to cur. So what does that mean? cur now represents a stream of Ints, filtered to NOT be divisible by 2!.

In the next loop, we take the first number off the cur channel, and it's a 3. The next prime. Why is it a 3? Because filter(2) allowed it to pass (3 % 2 != 0). This is the fun part. Now we take cur (a filtered list of numbers that are not divisible by 2) and pass it into a filter function, along with 3 (our most recent prime). Now cur represents a stream of numbers not divisible by 2 or 3. See where this is going?

Essentially at this point we have this:

```<code>numbers -> filter(2) -> filter(3)
</code>```

Or, read another (less precise wrt coroutines but easier to picture):

```<code>filter(3, filter(2, numbers))
</code>```

Any number that makes it to the head of cur is prime, because it passed through all of the filters.

Thanks for asking this question! "Go learn Kotlin Coroutines" has been on my research list for a couple of weeks and I had a good morning reading about them and figuring this out.

Body:
I'm going through the coroutines documentation for Kotlin and was following along pretty well until this example.  I'm having a really difficult time understanding how it's calculating when it finds a prime number, and specifically how the return from the filter function is both being returned and assigned to cur, as well as still producing numbers from the numbersFrom method.

I've added debugging statements to try and follow the various coroutines that are running, but I'm still lost on the logical flow of when it starts new coroutines and receives numbers from others.

https://github.com/Kotlin/kotlinx.coroutines/blob/master/coroutines-guide.md#prime-numbers-with-pipeline

The code:

fun log(msg: String) = println("[${Thread.currentThread().name}] $msg")

fun main(args: Array<String>) = runBlocking<Unit> {
    var cur = numbersFrom(context, 2)
    for (i in 1..10) {
        val prime = cur.receive()
        println(prime)
        cur = filter(context, cur, prime)
    }
}

fun numbersFrom(context: CoroutineContext, start: Int) = produce<Int>(context) {
       var x = start
    while (true) {
        log("NumbersFrom Send: ${x}")
        send(x++)
    } // infinite stream of integers from start
}

fun filter(context: CoroutineContext, numbers: ReceiveChannel<Int>, prime: Int) = produce<Int>(context) {
    for (x in numbers) {
        log("filter ${x}, prime ${prime}")
        if (x % prime != 0) {
            send(x)
        }
    }
}

Outout:

[main @coroutine#2] NumbersFrom Send: 2
[main @coroutine#2] NumbersFrom Send: 3
2
[main @coroutine#3] filter 3, prime 2
[main @coroutine#2] NumbersFrom Send: 4
[main @coroutine#2] NumbersFrom Send: 5
3
[main @coroutine#3] filter 4, prime 2
[main @coroutine#3] filter 5, prime 2
[main @coroutine#4] filter 5, prime 3
[main @coroutine#2] NumbersFrom Send: 6
[main @coroutine#3] filter 6, prime 2
5
[main @coroutine#2] NumbersFrom Send: 7
[main @coroutine#2] NumbersFrom Send: 8
[main @coroutine#3] filter 7, prime 2
[main @coroutine#3] filter 8, prime 2
[main @coroutine#4] filter 7, prime 3
[main @coroutine#2] NumbersFrom Send: 9
[main @coroutine#2] NumbersFrom Send: 10
[main @coroutine#5] filter 7, prime 5
[main @coroutine#3] filter 9, prime 2
[main @coroutine#3] filter 10, prime 2
7
[main @coroutine#4] filter 9, prime 3
[main @coroutine#2] NumbersFrom Send: 11
[main @coroutine#2] NumbersFrom Send: 12
[main @coroutine#3] filter 11, prime 2
[main @coroutine#3] filter 12, prime 2
[main @coroutine#4] filter 11, prime 3
[main @coroutine#2] NumbersFrom Send: 13
[main @coroutine#2] NumbersFrom Send: 14
[main @coroutine#5] filter 11, prime 5
[main @coroutine#3] filter 13, prime 2
[main @coroutine#3] filter 14, prime 2
[main @coroutine#6] filter 11, prime 7
[main @coroutine#4] filter 13, prime 3
[main @coroutine#2] NumbersFrom Send: 15
[main @coroutine#2] NumbersFrom Send: 16
11
[main @coroutine#5] filter 13, prime 5
[main @coroutine#3] filter 15, prime 2
[main @coroutine#3] filter 16, prime 2
[main @coroutine#6] filter 13, prime 7
[main @coroutine#4] filter 15, prime 3
[main @coroutine#2] NumbersFrom Send: 17
[main @coroutine#2] NumbersFrom Send: 18
[main @coroutine#7] filter 13, prime 11
[main @coroutine#3] filter 17, prime 2
[main @coroutine#3] filter 18, prime 2
13
[main @coroutine#4] filter 17, prime 3
[main @coroutine#2] NumbersFrom Send: 19
[main @coroutine#2] NumbersFrom Send: 20
[main @coroutine#5] filter 17, prime 5
[main @coroutine#3] filter 19, prime 2
[main @coroutine#3] filter 20, prime 2
[main @coroutine#6] filter 17, prime 7
[main @coroutine#4] filter 19, prime 3
[main @coroutine#2] NumbersFrom Send: 21
[main @coroutine#2] NumbersFrom Send: 22
[main @coroutine#7] filter 17, prime 11
[main @coroutine#5] filter 19, prime 5
[main @coroutine#3] filter 21, prime 2
[main @coroutine#3] filter 22, prime 2
[main @coroutine#8] filter 17, prime 13
[main @coroutine#6] filter 19, prime 7
[main @coroutine#4] filter 21, prime 3
[main @coroutine#2] NumbersFrom Send: 23
[main @coroutine#2] NumbersFrom Send: 24
17
[main @coroutine#7] filter 19, prime 11
[main @coroutine#3] filter 23, prime 2
[main @coroutine#3] filter 24, prime 2
[main @coroutine#8] filter 19, prime 13
[main @coroutine#4] filter 23, prime 3
[main @coroutine#2] NumbersFrom Send: 25
[main @coroutine#2] NumbersFrom Send: 26
[main @coroutine#9] filter 19, prime 17
[main @coroutine#5] filter 23, prime 5
[main @coroutine#3] filter 25, prime 2
[main @coroutine#3] filter 26, prime 2
19
[main @coroutine#6] filter 23, prime 7
[main @coroutine#4] filter 25, prime 3
[main @coroutine#2] NumbersFrom Send: 27
[main @coroutine#2] NumbersFrom Send: 28
[main @coroutine#7] filter 23, prime 11
[main @coroutine#5] filter 25, prime 5
[main @coroutine#3] filter 27, prime 2
[main @coroutine#3] filter 28, prime 2
[main @coroutine#8] filter 23, prime 13
[main @coroutine#4] filter 27, prime 3
[main @coroutine#2] NumbersFrom Send: 29
[main @coroutine#2] NumbersFrom Send: 30
[main @coroutine#9] filter 23, prime 17
[main @coroutine#3] filter 29, prime 2
[main @coroutine#3] filter 30, prime 2
[main @coroutine#10] filter 23, prime 19
[main @coroutine#4] filter 29, prime 3
[main @coroutine#2] NumbersFrom Send: 31
[main @coroutine#2] NumbersFrom Send: 32
23
[main @coroutine#5] filter 29, prime 5
[main @coroutine#3] filter 31, prime 2
[main @coroutine#3] filter 32, prime 2
[main @coroutine#6] filter 29, prime 7
[main @coroutine#4] filter 31, prime 3
[main @coroutine#2] NumbersFrom Send: 33
[main @coroutine#2] NumbersFrom Send: 34
[main @coroutine#7] filter 29, prime 11
[main @coroutine#5] filter 31, prime 5
[main @coroutine#3] filter 33, prime 2
[main @coroutine#3] filter 34, prime 2
[main @coroutine#8] filter 29, prime 13
[main @coroutine#6] filter 31, prime 7
[main @coroutine#4] filter 33, prime 3
[main @coroutine#2] NumbersFrom Send: 35
[main @coroutine#2] NumbersFrom Send: 36
[main @coroutine#9] filter 29, prime 17
[main @coroutine#7] filter 31, prime 11
[main @coroutine#3] filter 35, prime 2
[main @coroutine#3] filter 36, prime 2
[main @coroutine#10] filter 29, prime 19
[main @coroutine#8] filter 31, prime 13
[main @coroutine#4] filter 35, prime 3
[main @coroutine#2] NumbersFrom Send: 37
[main @coroutine#2] NumbersFrom Send: 38
[main @coroutine#11] filter 29, prime 23
[main @coroutine#9] filter 31, prime 17
[main @coroutine#5] filter 35, prime 5
[main @coroutine#3] filter 37, prime 2
[main @coroutine#3] filter 38, prime 2
29
[main @coroutine#10] filter 31, prime 19
[main @coroutine#4] filter 37, prime 3
[main @coroutine#2] NumbersFrom Send: 39

Body:
The point of the example is to implement the Sieve of Eratosthenes. In other words, to find prime numbers by filtering out numbers that can't be prime because of their divisibility. Anything left is a prime.

Let's look at what we have. I'm going to ignore all of the context variables for now, it just makes things easier to talk about.

First, we have a function called numbersFrom, which is just an endless sequence of integers starting at 2 (in this case).

We also have function called filter, which takes in a channel, and a number which is presumably prime. Looking at the return type, we can see that this function returns a new producer. In order to produce results (Ints in this case), the send function can be called. Looking at the body of the function, filter will accept numbers off the channel (via send) and REJECT anything that is evenly divisible by the prime number (by doing nothing).

For example, if the channel produces a 4 and the prime is a 2, that is rejected. On the other hand, if the channel produces a 5 and the prime is a 2, it will send that number along. It should now become obvious that filter does what its name says - read inputs, find the ones it likes, send them along to its output.

Now let's look at the main function. First we create a stream of numbers starting at 2 (what a coincidence, the first prime!) and assign that to cur. So far, so good.

Next, we start a loop. I reduced the 10 to a 3 to make things easier to understand, but essentially that number means how many primes the main method will calculate. If you want the first 100 primes, set it to 100.

In the loop, we take the first number off the numbers list, by calling receive() on cur. This is a suspending function. And as I mentioned above, it will get a 2 as its first prime value.

And now here is the fun part. We take that 2, and use it as the basis for a call to filter, along with cur, which is currently the stream of Ints, and reassign that to cur. So what does that mean? cur now represents a stream of Ints, filtered to NOT be divisible by 2!.

In the next loop, we take the first number off the cur channel, and it's a 3. The next prime. Why is it a 3? Because filter(2) allowed it to pass (3 % 2 != 0). This is the fun part. Now we take cur (a filtered list of numbers that are not divisible by 2) and pass it into a filter function, along with 3 (our most recent prime). Now cur represents a stream of numbers not divisible by 2 or 3. See where this is going?

Essentially at this point we have this:

numbers -> filter(2) -> filter(3)

Or, read another (less precise wrt coroutines but easier to picture):

filter(3, filter(2, numbers))

Any number that makes it to the head of cur is prime, because it passed through all of the filters.

Thanks for asking this question! "Go learn Kotlin Coroutines" has been on my research list for a couple of weeks and I had a good morning reading about them and figuring this out.


来源: stackexchange

问:
pthread_cond_wait and pthread_mutex_lock priority?
I have a multiple read threads and one write thread. If I lock mutex on one of the read threads and send broadcast from it, is it guaranteed that mutex will be locked by write thread waiting on pthread_cond_wait() or is there a possibility that another read thread that is wainting on pthread_mutex_lock() will lock mutex? Main question is does pthread_cond_wait() have priority over pthread_mutex_lock()?

If not, how can I achieve that the mutex will always be locked by write thread on pthread_cond_broadcast()?

Example

Read thread:

```<code>pthread_mutex_lock(mutex);
pthread_cond_broadcast(cond);
pthread_mutex_unlock(mutex);
</code>```

Write thread:

```<code>pthread_mutex_lock(&mutex);
pthread_cond_wait(&cond, &mutex);
</code>```

答:
Let's assume both threads, read and write, reach the pthread_mutex_lock in the same moment. So, either write thread acquire the mutex on pthread_mutex_lock call, or read thread.

If it would be the write thread, the read one will wait on pthread_mutex_lock. The write, by calling pthread_cond_wait releases mutex and blocks on cond. It is done atomically. So, when read thread is grantex the mutex, we can be sure the the read one waits on cond. So, broadcast on cond reaches the write thread, it no more waits on cond but - still in scope of pthread_cond_wait - tries to get a lock on mutex (hold be read thread). After broadcasting cond the read thread releases the mutex and it goes to write thread. So write thread finally exits from pthread_cond_wait having the mutex locked. Remember to unlock it later.

If it would be the read thread, the write one will wait on pthread_mutex_lock, the read will broadcast a signal on cond then release the mutex. After then the write thread acquires the mutex on pthread_mutex_lock and immediately releases in it pthread_cond_wait waiting for cond (please note, that previous cond broadcast has no effect on current pthread_cond_wait). In the next iteration of read thread it acquires lock onmutex, send broadcast on cond and unlock mutex. It means the write thread moves forward on cond and acquires lock on mutex.

Does it answer your question about priority?

Update after comment.

Let's assume we have one thread (let's name it A for future reference) holding the lock on mutex and few other trying to acquire the same lock. As soon as the lock is released by first thread, there is no predictable which thread would acquire lock. Moreover, if the A thread has a loop and tries to reacquire lock on mutex, there is a chance it would be granted this lock and other threads would keep waiting. Adding pthread_cond_wait doesn't change anything in scope of granting a lock.

Let me quote fragments of POSIX specification (see https://stackoverflow.com/a/9625267/2989411 for reference):

These functions atomically release mutex and cause the calling thread to block on the condition variable cond; atomically here means "atomically with respect to access by another thread to the mutex and then the condition variable". That is, if another thread is able to acquire the mutex after the about-to-block thread has released it, then a subsequent call to pthread_cond_broadcast() or pthread_cond_signal() in that thread shall behave as if it were issued after the about-to-block thread has blocked.

And this is only guarantee given by standard regarding order of operations. Order of granting the lock to other threads is rather unpredictable and it changes depending on some very subtle fluctuation in timing.

For only mutex related code, please play a little with following code:

#define _GNU_SOURCE
#include <pthread.h>

#include <stdio.h>
#include <unistd.h>

pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;

void *th(void *arg) {
    int i;
    char *s = arg;
    for (i = 0; i < 10; ++i) {
        pthread_mutex_lock(&mutex);
        printf("%s %d\n", s, i);
        //sleep(1);
        pthread_mutex_unlock(&mutex);
#if 0
        pthread_yield();
#endif
    }
    return NULL;
}

int main() {
    int i;
    for (i = 0; i < 10; ++i) {
        pthread_t t1, t2, t3;
        printf("================================\n");
        pthread_create(&t1, NULL, th, "t1");
        pthread_create(&t2, NULL, th, "     t2");
        pthread_create(&t3, NULL, th, "            t3");
        pthread_join(t1, NULL);
        pthread_join(t2, NULL);
        pthread_join(t3, NULL);
    }
    return 0;
}
```

<p>On one machine (single CPU) it always shows whole loop from t3, then t2 and finally from t1. On another (2 cores) the order of threads is more random, but almost always it shows whole loop for each thread before granting the mutex to other thread. Rarely there is a situation like:</p>

```t1 8
t1 9
            t3 0
     t2 0
     t2 1
     [removed other t2 output]
     t2 8
     t2 9
            t3 1
            t3 2
```

<p>Enable <code>pthread_yield</code> by replacing <code>#if 0</code> with <code>#if 1</code> and watch results and check output. For me it works in a way two threads display their output interlaced, then third thread finally has a chance to work. Add another or more thread. Play with sleep, etc. It confirms the random behaviour.</p>

<p>If you wish to experiment a little, compile and run following piece of code. It's an example of single producer - multiple consumers model. It can be run with two parameters: first is the number of consumer threads, second is the length of produced data series. If no parameters are given there is one consumer thread and 120 items to be processed. I also recommend with sleep/usleep in places marked <code>/* play here */</code>: change the value of arguments, remove the sleep at all, move it - when appropriate - to critical section or replace with pthread_yield and observe changes in behaviour.</p>

```#define _GNU_SOURCE
#include <assert.h>
#include <limits.h>
#include <pthread.h>
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <unistd.h>

struct data_t {
    int seq;
    int payload;
    struct data_t *next;
};

pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;
pthread_cond_t cond = PTHREAD_COND_INITIALIZER;
struct data_t *first = NULL, *last = NULL;
int in_progress = 1;
int num_data = 120;

void push(int seq, int payload) {
    struct data_t *e;
    e = malloc(sizeof(struct data_t));
    e->seq = seq;
    e->payload = payload;
    e->next = NULL;
    if (last == NULL) {
        assert(first == NULL);
        first = last = e;
    } else {
        last->next = e;
        last = e;
    }
}

struct data_t pop() {
    struct data_t res = {0};
    if (first == NULL) {
        res.seq = -1;
    } else {
        res.seq = first->seq;
        res.payload = first->payload;
        first = first->next;
        if (first == NULL) {
            last = NULL;
        }
    }
    return res;
}

void *producer(void *arg __attribute__((unused))) {
    int i;
    printf("producer created\n");
    for (i = 0; i < num_data; ++i) {
        int val;
        sleep(1); /* play here */
        pthread_mutex_lock(&mutex);
        val = rand() / (INT_MAX / 1000);
        push(i, val);
        pthread_mutex_unlock(&mutex);
        pthread_cond_signal(&cond);
        printf("prod %3d %3d signaled\n", i, val);
    }
    in_progress = 0;
    printf("prod end\n");
    pthread_cond_broadcast(&cond);
    printf("prod end signaled\n");
    return NULL;
}

void *consumer(void *arg) {
    char c_id[1024];
    int t_id = *(int *)arg;
    sprintf(c_id, "%*s c %02d", t_id % 10, "", t_id);
    printf("%s created\n", c_id);
    while (1) {
        struct data_t item;
        pthread_mutex_lock(&mutex);
        item = pop();
        while (item.seq == -1 && in_progress) {
            printf("%s waits for data\n", c_id);
            pthread_cond_wait(&cond, &mutex);
            printf("%s got signal\n", c_id);
            item = pop();
        }
        if (!in_progress && item.seq == -1) {
            printf("%s detected end of data.\n", c_id);
            pthread_mutex_unlock(&mutex);
            break;
        }
        pthread_mutex_unlock(&mutex);
        printf("%s processing %3d %3d\n", c_id, item.seq, item.payload);
        sleep(item.payload % 10); /* play here */
        printf("%s processed  %3d %3d\n", c_id, item.seq, item.payload);
    }
    printf("%s end\n", c_id);
    return NULL;
}

int main(int argc, char *argv[]) {
    int num_cons = 1;
    pthread_t t_prod;
    pthread_t *t_cons;
    int i;
    int *nums;
    if (argc > 1) {
        num_cons = atoi(argv[1]);
        if (num_cons == 0) {
            num_cons = 1;
        }
        if (num_cons > 99) {
            num_cons = 99;
        }
    }
    if (argc > 2) {
        num_data = atoi(argv[2]);
        if (num_data < 10) {
            num_data = 10;
        }
        if (num_data > 600) {
            num_data = 600;
        }
    }

    printf("Spawning %d consumer%s for %d items.\n", num_cons, num_cons == 1 ? "" : "s", num_data);
    t_cons = malloc(sizeof(pthread_t) * num_cons);
    nums = malloc(sizeof(int) * num_cons);
    if (!t_cons || !nums) {
        printf("Out of memory!\n");
        exit(1);
    }
    srand(time(NULL));
    pthread_create(&t_prod, NULL, producer, NULL);

    for (i = 0; i < num_cons; ++i) {
        nums[i] = i + 1;
        usleep(100000); /* play here */
        pthread_create(t_cons + i, NULL, consumer, nums + i);
    }

    pthread_join(t_prod, NULL);

    for (i = 0; i < num_cons; ++i) {
        pthread_join(t_cons[i], NULL);
    }
    free(nums);
    free(t_cons);

    return 0;
}
```

I hope I have cleared your doubts and gave you some code to experiment and gain some confidence about pthread behaviour.

ContentLicense: CC BY-SA 3.0

Body:
I have a multiple read threads and one write thread. If I lock mutex on one of the read threads and send broadcast from it, is it guaranteed that mutex will be locked by write thread waiting on pthread_cond_wait() or is there a possibility that another read thread that is wainting on pthread_mutex_lock() will lock mutex? Main question is does pthread_cond_wait() have priority over pthread_mutex_lock()?

If not, how can I achieve that the mutex will always be locked by write thread on pthread_cond_broadcast()?

Example

Read thread:

pthread_mutex_lock(mutex);
pthread_cond_broadcast(cond);
pthread_mutex_unlock(mutex);

Write thread:

pthread_mutex_lock(&mutex);
pthread_cond_wait(&cond, &mutex);

Body:
Let's assume both threads, read and write, reach the pthread_mutex_lock in the same moment. So, either write thread acquire the mutex on pthread_mutex_lock call, or read thread.

If it would be the write thread, the read one will wait on pthread_mutex_lock. The write, by calling pthread_cond_wait releases mutex and blocks on cond. It is done atomically. So, when read thread is grantex the mutex, we can be sure the the read one waits on cond. So, broadcast on cond reaches the write thread, it no more waits on cond but - still in scope of pthread_cond_wait - tries to get a lock on mutex (hold be read thread). After broadcasting cond the read thread releases the mutex and it goes to write thread. So write thread finally exits from pthread_cond_wait having the mutex locked. Remember to unlock it later.

If it would be the read thread, the write one will wait on pthread_mutex_lock, the read will broadcast a signal on cond then release the mutex. After then the write thread acquires the mutex on pthread_mutex_lock and immediately releases in it pthread_cond_wait waiting for cond (please note, that previous cond broadcast has no effect on current pthread_cond_wait). In the next iteration of read thread it acquires lock onmutex, send broadcast on cond and unlock mutex. It means the write thread moves forward on cond and acquires lock on mutex.

Does it answer your question about priority?

Update after comment.

Let's assume we have one thread (let's name it A for future reference) holding the lock on mutex and few other trying to acquire the same lock. As soon as the lock is released by first thread, there is no predictable which thread would acquire lock. Moreover, if the A thread has a loop and tries to reacquire lock on mutex, there is a chance it would be granted this lock and other threads would keep waiting. Adding pthread_cond_wait doesn't change anything in scope of granting a lock.

Let me quote fragments of POSIX specification (see https://stackoverflow.com/a/9625267/2989411 for reference):

These functions atomically release mutex and cause the calling thread to block on the condition variable cond; atomically here means "atomically with respect to access by another thread to the mutex and then the condition variable". That is, if another thread is able to acquire the mutex after the about-to-block thread has released it, then a subsequent call to pthread_cond_broadcast() or pthread_cond_signal() in that thread shall behave as if it were issued after the about-to-block thread has blocked.

And this is only guarantee given by standard regarding order of operations. Order of granting the lock to other threads is rather unpredictable and it changes depending on some very subtle fluctuation in timing.

For only mutex related code, please play a little with following code:

#define _GNU_SOURCE
#include <pthread.h>

#include <stdio.h>
#include <unistd.h>

pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;

void *th(void *arg) {
    int i;
    char *s = arg;
    for (i = 0; i < 10; ++i) {
        pthread_mutex_lock(&mutex);
        printf("%s %d\n", s, i);
        //sleep(1);
        pthread_mutex_unlock(&mutex);
#if 0
        pthread_yield();
#endif
    }
    return NULL;
}

int main() {
    int i;
    for (i = 0; i < 10; ++i) {
        pthread_t t1, t2, t3;
        printf("================================\n");
        pthread_create(&t1, NULL, th, "t1");
        pthread_create(&t2, NULL, th, "     t2");
        pthread_create(&t3, NULL, th, "            t3");
        pthread_join(t1, NULL);
        pthread_join(t2, NULL);
        pthread_join(t3, NULL);
    }
    return 0;
}

On one machine (single CPU) it always shows whole loop from t3, then t2 and finally from t1. On another (2 cores) the order of threads is more random, but almost always it shows whole loop for each thread before granting the mutex to other thread. Rarely there is a situation like:

t1 8
t1 9
            t3 0
     t2 0
     t2 1
     [removed other t2 output]
     t2 8
     t2 9
            t3 1
            t3 2

Enable pthread_yield by replacing #if 0 with #if 1 and watch results and check output. For me it works in a way two threads display their output interlaced, then third thread finally has a chance to work. Add another or more thread. Play with sleep, etc. It confirms the random behaviour.

If you wish to experiment a little, compile and run following piece of code. It's an example of single producer - multiple consumers model. It can be run with two parameters: first is the number of consumer threads, second is the length of produced data series. If no parameters are given there is one consumer thread and 120 items to be processed. I also recommend with sleep/usleep in places marked /* play here */: change the value of arguments, remove the sleep at all, move it - when appropriate - to critical section or replace with pthread_yield and observe changes in behaviour.

#define _GNU_SOURCE
#include <assert.h>
#include <limits.h>
#include <pthread.h>
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <unistd.h>

struct data_t {
    int seq;
    int payload;
    struct data_t *next;
};

pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;
pthread_cond_t cond = PTHREAD_COND_INITIALIZER;
struct data_t *first = NULL, *last = NULL;
int in_progress = 1;
int num_data = 120;

void push(int seq, int payload) {
    struct data_t *e;
    e = malloc(sizeof(struct data_t));
    e->seq = seq;
    e->payload = payload;
    e->next = NULL;
    if (last == NULL) {
        assert(first == NULL);
        first = last = e;
    } else {
        last->next = e;
        last = e;
    }
}

struct data_t pop() {
    struct data_t res = {0};
    if (first == NULL) {
        res.seq = -1;
    } else {
        res.seq = first->seq;
        res.payload = first->payload;
        first = first->next;
        if (first == NULL) {
            last = NULL;
        }
    }
    return res;
}

void *producer(void *arg __attribute__((unused))) {
    int i;
    printf("producer created\n");
    for (i = 0; i < num_data; ++i) {
        int val;
        sleep(1); /* play here */
        pthread_mutex_lock(&mutex);
        val = rand() / (INT_MAX / 1000);
        push(i, val);
        pthread_mutex_unlock(&mutex);
        pthread_cond_signal(&cond);
        printf("prod %3d %3d signaled\n", i, val);
    }
    in_progress = 0;
    printf("prod end\n");
    pthread_cond_broadcast(&cond);
    printf("prod end signaled\n");
    return NULL;
}

void *consumer(void *arg) {
    char c_id[1024];
    int t_id = *(int *)arg;
    sprintf(c_id, "%*s c %02d", t_id % 10, "", t_id);
    printf("%s created\n", c_id);
    while (1) {
        struct data_t item;
        pthread_mutex_lock(&mutex);
        item = pop();
        while (item.seq == -1 && in_progress) {
            printf("%s waits for data\n", c_id);
            pthread_cond_wait(&cond, &mutex);
            printf("%s got signal\n", c_id);
            item = pop();
        }
        if (!in_progress && item.seq == -1) {
            printf("%s detected end of data.\n", c_id);
            pthread_mutex_unlock(&mutex);
            break;
        }
        pthread_mutex_unlock(&mutex);
        printf("%s processing %3d %3d\n", c_id, item.seq, item.payload);
        sleep(item.payload % 10); /* play here */
        printf("%s processed  %3d %3d\n", c_id, item.seq, item.payload);
    }
    printf("%s end\n", c_id);
    return NULL;
}

int main(int argc, char *argv[]) {
    int num_cons = 1;
    pthread_t t_prod;
    pthread_t *t_cons;
    int i;
    int *nums;
    if (argc > 1) {
        num_cons = atoi(argv[1]);
        if (num_cons == 0) {
            num_cons = 1;
        }
        if (num_cons > 99) {
            num_cons = 99;
        }
    }
    if (argc > 2) {
        num_data = atoi(argv[2]);
        if (num_data < 10) {
            num_data = 10;
        }
        if (num_data > 600) {
            num_data = 600;
        }
    }

    printf("Spawning %d consumer%s for %d items.\n", num_cons, num_cons == 1 ? "" : "s", num_data);
    t_cons = malloc(sizeof(pthread_t) * num_cons);
    nums = malloc(sizeof(int) * num_cons);
    if (!t_cons || !nums) {
        printf("Out of memory!\n");
        exit(1);
    }
    srand(time(NULL));
    pthread_create(&t_prod, NULL, producer, NULL);

    for (i = 0; i < num_cons; ++i) {
        nums[i] = i + 1;
        usleep(100000); /* play here */
        pthread_create(t_cons + i, NULL, consumer, nums + i);
    }

    pthread_join(t_prod, NULL);

    for (i = 0; i < num_cons; ++i) {
        pthread_join(t_cons[i], NULL);
    }
    free(nums);
    free(t_cons);

    return 0;
}

I hope I have cleared your doubts and gave you some code to experiment and gain some confidence about pthread behaviour.


问:
How to Retrieve all possible information about a LinkedIn Account using Typescript
Hi Currently I am developing Ionic2 framework app with social login, I have added Google plus and facebook button and working fine now I want Implement Linkedin login also I am using Typescript for that and I am not getting how to implement the function I am not getting But I have created app in  linkedin developer console
On linkedin developer console only javascript(Working only on index.html page,I want to add it to another page) and android methods are there could you please tell me how to implement REST Api method  </p>

答: Here is straight forward post about "how to implement REST Api method"</p>


问:
Get the text present inside the span in selenium
I have to get the value inside the span tag,How to get the value?Class name is same but when there is an error in any of the field for that class the text will be visible .For example i have twofields :
1)depositorname
2)company name
If company name is wrong,Then message is "Company name not found".This message is displayed in span tag were depositorname span tag doesnot have linktext value.
sameclass</p>

答: You need just to configure a situation when that span is visible. Find this span and make getText operation.</p>


问:
Grid "dirty" flag not updating
I am having trouble manually setting/removing the "dirty flag" indicator on the Kendo grid control.

I have extended the tutorial to preserve dirty indicators to include additional validation on the value field during the dataSource.change event:

A previously saved value (which contains an id) which has been modified to be 0 - this is a valid "dirty flag" (e.items[0].id > 0 && e.items[0].value === 0)

A value has been entered with a value greater than 0 - this is a valid "dirty flag" (e.items[0].value > 0)

Any other instance of value is not a valid "dirty flag" and therefore should be removed

If the user has left the value field "blank" i.e. "null", modify the value to 0 (if (!e.items[0].value) {e.items[0].value = 0;})

With these changes applied, the change event now looks like:

```<code>change: function (e) {
    if (e.action == "itemchange") {
        if ((e.items[0].id > 0 && e.items[0].value === 0) || e.items[0].value > 0) {
            e.items[0].dirtyFields = e.items[0].dirtyFields || {};
            e.items[0].dirtyFields[e.field] = true;
            _dirty = true;
        }
        else {
            if (!e.items[0].value) {
                e.items[0].value = 0;
            }
            e.items[0].dirty = false;
            e.items[0].dirtyFields = e.items[0].dirtyFields || {};
            e.items[0].dirtyFields[e.field] = false;
        }
        $("#grid").data("kendoGrid").refresh();
    }
}
</code>```

Upon making these changes, I can see the dirtyField function (which is the template of the value column) being triggered, and can also see the appropriate true/false values being supplied and the appropriate return taking place (which, I thought, should set/remove the "dirty flag" from the appropriate cells):

```<code>function dirtyField(data, fieldName){
    if(data.dirty && data.dirtyFields[fieldName]){
        return "<span class='k-dirty'></span>"
    }
    else{
        return "";
    }
}
</code>```

However, the "dirty flag" is not being removed until another cell within the grid is modified.

Here is a Dojo example to demonstrate the issue. In order to replicate:

Enter a value greater than 0 into the second row value cell (sets "dirty flag")

Delete the value from the second row value cell ("dirty flag" remains -> should now be gone based on change event logic)

Enter a value greater than 0 into the third row value cell (sets "dirty flag" on current cell, removes "dirty flag" from second row value cell)

答:
Your DataSource.change event is called before the grid cell is closed. So you refresh grid and cell changes are not properly reflected in the UI.

You should move grid refresh to grid cellClose event. Then grid refresh will be called after the cell is closed and everything works correctly.

```<code>$("#grid").kendoGrid({
    dataSource: dataSource,
    sortable: true,
    pageable: true,
    navigatable: true,
    height: 400,
    columns: [
        { field: "value", title: "Value", editor: decimal_NumberEditor, format: '{0:n2}', attributes: { class: "editable-cell" }, template: "#=dirtyField(data,'value')# #:value#" }],
    editable: true,
    cellClose: function(e) {
        $("#grid").data("kendoGrid").refresh();
    }
});
</code>```

Here is working example with events logging for better understangind of what's going on. See JS console:

http://dojo.telerik.com/ICIxUX/7

Title: Grid "dirty" flag not updating

Body:
I am having trouble manually setting/removing the "dirty flag" indicator on the Kendo grid control.

I have extended the tutorial to preserve dirty indicators to include additional validation on the value field during the dataSource.change event:

A previously saved value (which contains an id) which has been modified to be 0 - this is a valid "dirty flag" (e.items[0].id > 0 && e.items[0].value === 0)

A value has been entered with a value greater than 0 - this is a valid "dirty flag" (e.items[0].value > 0)

Any other instance of value is not a valid "dirty flag" and therefore should be removed

If the user has left the value field "blank" i.e. "null", modify the value to 0 (if (!e.items[0].value) {e.items[0].value = 0;})

With these changes applied, the change event now looks like:

change: function (e) {
    if (e.action == "itemchange") {
        if ((e.items[0].id > 0 && e.items[0].value === 0) || e.items[0].value > 0) {
            e.items[0].dirtyFields = e.items[0].dirtyFields || {};
            e.items[0].dirtyFields[e.field] = true;
            _dirty = true;
        }
        else {
            if (!e.items[0].value) {
                e.items[0].value = 0;
            }
            e.items[0].dirty = false;
            e.items[0].dirtyFields = e.items[0].dirtyFields || {};
            e.items[0].dirtyFields[e.field] = false;
        }
        $("#grid").data("kendoGrid").refresh();
    }
}

Upon making these changes, I can see the dirtyField function (which is the template of the value column) being triggered, and can also see the appropriate true/false values being supplied and the appropriate return taking place (which, I thought, should set/remove the "dirty flag" from the appropriate cells):

function dirtyField(data, fieldName){
    if(data.dirty && data.dirtyFields[fieldName]){
        return ""
    }
    else{
        return "";
    }
}

However, the "dirty flag" is not being removed until another cell within the grid is modified.

Here is a Dojo example to demonstrate the issue. In order to replicate:

Enter a value greater than 0 into the second row value cell (sets "dirty flag")

Delete the value from the second row value cell ("dirty flag" remains -> should now be gone based on change event logic)

Enter a value greater than 0 into the third row value cell (sets "dirty flag" on current cell, removes "dirty flag" from second row value cell)

Body:
Your DataSource.change event is called before the grid cell is closed. So you refresh grid and cell changes are not properly reflected in the UI.

You should move grid refresh to grid cellClose event. Then grid refresh will be called after the cell is closed and everything works correctly.

$("#grid").kendoGrid({
    dataSource: dataSource,
    sortable: true,
    pageable: true,
    navigatable: true,
    height: 400,
    columns: [
        { field: "value", title: "Value", editor: decimal_NumberEditor, format: '{0:n2}', attributes: { class: "editable-cell" }, template: "#=dirtyField(data,'value')# #:value#" }],
    editable: true,
    cellClose: function(e) {
        $("#grid").data("kendoGrid").refresh();
    }
});

Here is working example with events logging for better understangind of what's going on. See JS console:

http://dojo.telerik.com/ICIxUX/7


问:
How to weight an input?
I'm trying to train a simple model using TensorFlow.

I want to get an accurate prediction (98%+) for a new input into the trained model.

There is 500 Input's. 1 stands for a Price (500-200.000), 1 for a Construction-Year (1980-2017) and the 498 remaining are either true or false (0/1). Now the 498 Input's are really important (in fact the other two are almost obsolete). So it's all numeric.

I looked through the TensorFlow documentation and couldn't find any tutorial on how to weigh the different input's. e.g. Price/Year should only make up for "10%" of the Prediction (0.05 each) while the remainders make up for the rest (0.9).

Is there a solution for this?

答:
Problem

Construct a learning algorithm that does not choose all of its own weights, but instead only chooses some of its weights.  Specifically, given 500 features the first feature contributes 5% , the second features contributes 5% and the remaining 498 features contribute 95% to the final prediction.

Solution

This is very similar to the architecture of a collection of experts.  Instead of creating 1 network, you will create 3 networks :

a network that uses feature 1

a network that uses feature 2

a network that uses feature 3 through 500

You would create each of these networks as you would a regular network with independant weight matrices and output hypothesis.

That will end in some tensorflow code like

```<code>y_out_from_price = tf.nn.softmax( h_out_from_price )
y_out_from_year  = tf.nn.softmax( h_out_from_year  )
y_out_from_rest  = tf.nn.softmax( h_out_from_rest  )
</code>```

Where each of these is your categorization prediction.  Your final prediction is

```<code>y_out_final = 0.05 * y_out_from_price +
    0.05 * y_out_from_year +
    0.95 * y_out_from_rest
</code>```

My opinion is that this will underperform just using all the features.

ContentLicense: CC BY-SA 4.0

Title: How to weight an input?

Body:
Problem

Construct a learning algorithm that does not choose all of its own weights, but instead only chooses some of its weights.  Specifically, given 500 features the first feature contributes 5% , the second features contributes 5% and the remaining 498 features contribute 95% to the final prediction.

Solution

This is very similar to the architecture of a collection of experts.  Instead of creating 1 network, you will create 3 networks :

a network that uses feature 1

a network that uses feature 2

a network that uses feature 3 through 500

You would create each of these networks as you would a regular network with independant weight matrices and output hypothesis.

That will end in some tensorflow code like

y_out_from_price = tf.nn.softmax( h_out_from_price )
y_out_from_year  = tf.nn.softmax( h_out_from_year  )
y_out_from_rest  = tf.nn.softmax( h_out_from_rest  )

Where each of these is your categorization prediction.  Your final prediction is

y_out_final = 0.05 * y_out_from_price +
    0.05 * y_out_from_year +
    0.95 * y_out_from_rest

My opinion is that this will underperform just using all the features.


问:
Request throttle or Spam protection on direct line endpoints (Bot Framework)?
Does the Bot Framework's direct line endpoints throttles requests or has Spam protection?

We will soon put a bot online and are expecting heavy traffic. We're currently executing load tests and are having problems (timeouts) when multiple connections are made to direct line simultaneously.

Thanks!

答: You should perform load tests directly against your bot's endpoint. Load tests should not be done through direct line.</p>


问:
What is the return type of resolve and reject function of a Promise?
I am trying to find the return type of resolve and reject function of a Promise I am creating with typescript, so that tslint does not complain based on the typedef rules.

Here is the code :

promises.ts

```<code>const promise: Promise<number> = new Promise((resolve, reject): void => {
    //the resolve / reject functions control the fate of the promise
    resolve(123);
});

//The promise fate can be subscribed to using .then (if resolved) or .catch (if rejected)
promise.then((res) => {
    console.log('I get called:', res === 123);      //I get called: true
});
</code>```

tslint.json

```<code>{
    "defaultSeverity": "error",
    "extends": [
        "tslint:recommended"
    ],
    "jsRules": {},
    "rules": {
        "eofline": false,
        "no-console": false,
        "no-consecutive-blank-lines": false,
        "comment-format": false,
        "no-trailing-whitespace": false,
        "quotemark": false,
        "typedef": [true, "call-signature", "arrow-call-signature", "parameter", "arrow-parameter", "property-declaration", "variable-declaration", "member-variable-declaration"],
        "typedef-whitespace": false,
        "whitespace": false
    },
    "rulesDirectory": []
}
</code>```

tsconfig.json

```<code>{
  "compilerOptions": {
    /* Basic Options */
    "target": "es5",                          /* Specify ECMAScript target version: 'ES3' (default), 'ES5', 'ES2015', 'ES2016', 'ES2017', or 'ESNEXT'. */
    "module": "commonjs",                     /* Specify module code generation: 'commonjs', 'amd', 'system', 'umd' or 'es2015'. */
    // "lib": [],                             /* Specify library files to be included in the compilation:  */
    // "allowJs": true,                       /* Allow javascript files to be compiled. */
    // "checkJs": true,                       /* Report errors in .js files. */
    // "jsx": "preserve",                     /* Specify JSX code generation: 'preserve', 'react-native', or 'react'. */
    // "declaration": true,                   /* Generates corresponding '.d.ts' file. */
    "sourceMap": true,                     /* Generates corresponding '.map' file. */
    // "outFile": "./",                       /* Concatenate and emit output to single file. */
     "outDir": "./build/",                        /* Redirect output structure to the directory. */
    // "rootDir": "./",                       /* Specify the root directory of input files. Use to control the output directory structure with --outDir. */
    // "removeComments": true,                /* Do not emit comments to output. */
    // "noEmit": true,                        /* Do not emit outputs. */
    // "importHelpers": true,                 /* Import emit helpers from 'tslib'. */
    // "downlevelIteration": true,            /* Provide full support for iterables in 'for-of', spread, and destructuring when targeting 'ES5' or 'ES3'. */
    // "isolatedModules": true,               /* Transpile each file as a separate module (similar to 'ts.transpileModule'). */

    /* Strict Type-Checking Options */
    "strict": true,                            /* Enable all strict type-checking options. */
    "noImplicitAny": true,                      /* Raise error on expressions and declarations with an implied 'any' type. */
    "strictNullChecks": true,              /* Enable strict null checks. */
    // "noImplicitThis": true,                /* Raise error on 'this' expressions with an implied 'any' type. */
    // "alwaysStrict": true,                  /* Parse in strict mode and emit "use strict" for each source file. */

    /* Additional Checks */
    // "noUnusedLocals": true,                /* Report errors on unused locals. */
    // "noUnusedParameters": true,            /* Report errors on unused parameters. */
    // "noImplicitReturns": true,             /* Report error when not all code paths in function return a value. */
    // "noFallthroughCasesInSwitch": true,    /* Report errors for fallthrough cases in switch statement. */

    /* Module Resolution Options */
    // "moduleResolution": "node",            /* Specify module resolution strategy: 'node' (Node.js) or 'classic' (TypeScript pre-1.6). */
    // "baseUrl": "./",                       /* Base directory to resolve non-absolute module names. */
    // "paths": {},                           /* A series of entries which re-map imports to lookup locations relative to the 'baseUrl'. */
    // "rootDirs": [],                        /* List of root folders whose combined content represents the structure of the project at runtime. */
    // "typeRoots": [],                       /* List of folders to include type definitions from. */
    // "types": [],                           /* Type declaration files to be included in compilation. */
    // "allowSyntheticDefaultImports": true,  /* Allow default imports from modules with no default export. This does not affect code emit, just typechecking. */

    /* Source Map Options */
    // "sourceRoot": "./",                    /* Specify the location where debugger should locate TypeScript files instead of source locations. */
    // "mapRoot": "./",                       /* Specify the location where debugger should locate map files instead of generated locations. */
    // "inlineSourceMap": true,               /* Emit a single file with source maps instead of having a separate file. */
    // "inlineSources": true,                 /* Emit the source alongside the sourcemaps within a single file; requires '--inlineSourceMap' or '--sourceMap' to be set. */

    /* Experimental Options */
    // "experimentalDecorators": true,        /* Enables experimental support for ES7 decorators. */
    // "emitDecoratorMetadata": true,         /* Enables experimental support for emitting type metadata for decorators. */
    "lib": [
      "dom",
      "es5",
      "es2015.promise"
    ]
  }
}
</code>```

package.json

```<code>{
  "name": "TypescriptProject5",
  "version": "1.0.0",
  "description": "",
  "main": "index.js",
  "scripts": {
    "start": "webpack-dev-server",
    "build": "webpack --watch",
    "test": "echo \"Error: no test specified\" && exit 1"
  },
  "keywords": [],
  "author": "",
  "license": "ISC",
  "devDependencies": {
    "ts-loader": "^2.1.0",
    "tslint": "^5.4.2",
    "typescript": "^2.3.4",
    "webpack": "^2.6.1",
    "webpack-dev-server": "^2.4.5",
    "write-file-webpack-plugin": "^4.0.2"
  },
  "dependencies": {
    "es6-promise": "^4.1.0"
  }
}
</code>```

Right now tslint complains about resolve, reject and res (expected arrow parameter to have a typedef)

Update #2 : This code does not give me any tslint or TS errors

```<code>const promise: Promise<number> = new Promise((resolve: (value?: {} | PromiseLike<{}> | undefined) => void, reject: (reason?: any) => void): void => {
    //the resolve / reject functions control the fate of the promise
    resolve(123);
});

//The promise fate can be subscribed to using .then (if resolved) or .catch (if rejected)
promise.then((res: number) => {
    console.log('I get called:', res === 123);      //I get called: true
});
</code>```

答:
This is trivial to test.

new Promise(function (res, rej) {
    console.log(res());
});

new Promise(function (res, rej) {
    console.log(rej());
});```

They both return undefined.

Body:
I am trying to find the return type of resolve and reject function of a Promise I am creating with typescript, so that tslint does not complain based on the typedef rules.

Here is the code :

promises.ts

const promise: Promise<number> = new Promise((resolve, reject): void => {
    //the resolve / reject functions control the fate of the promise
    resolve(123);
});

//The promise fate can be subscribed to using .then (if resolved) or .catch (if rejected)
promise.then((res) => {
    console.log('I get called:', res === 123);      //I get called: true
});

tslint.json

{
    "defaultSeverity": "error",
    "extends": [
        "tslint:recommended"
    ],
    "jsRules": {},
    "rules": {
        "eofline": false,
        "no-console": false,
        "no-consecutive-blank-lines": false,
        "comment-format": false,
        "no-trailing-whitespace": false,
        "quotemark": false,
        "typedef": [true, "call-signature", "arrow-call-signature", "parameter", "arrow-parameter", "property-declaration", "variable-declaration", "member-variable-declaration"],
        "typedef-whitespace": false,
        "whitespace": false
    },
    "rulesDirectory": []
}

tsconfig.json

{
  "compilerOptions": {
    /* Basic Options */
    "target": "es5",                          /* Specify ECMAScript target version: 'ES3' (default), 'ES5', 'ES2015', 'ES2016', 'ES2017', or 'ESNEXT'. */
    "module": "commonjs",                     /* Specify module code generation: 'commonjs', 'amd', 'system', 'umd' or 'es2015'. */
    // "lib": [],                             /* Specify library files to be included in the compilation:  */
    // "allowJs": true,                       /* Allow javascript files to be compiled. */
    // "checkJs": true,                       /* Report errors in .js files. */
    // "jsx": "preserve",                     /* Specify JSX code generation: 'preserve', 'react-native', or 'react'. */
    // "declaration": true,                   /* Generates corresponding '.d.ts' file. */
    "sourceMap": true,                     /* Generates corresponding '.map' file. */
    // "outFile": "./",                       /* Concatenate and emit output to single file. */
     "outDir": "./build/",                        /* Redirect output structure to the directory. */
    // "rootDir": "./",                       /* Specify the root directory of input files. Use to control the output directory structure with --outDir. */
    // "removeComments": true,                /* Do not emit comments to output. */
    // "noEmit": true,                        /* Do not emit outputs. */
    // "importHelpers": true,                 /* Import emit helpers from 'tslib'. */
    // "downlevelIteration": true,            /* Provide full support for iterables in 'for-of', spread, and destructuring when targeting 'ES5' or 'ES3'. */
    // "isolatedModules": true,               /* Transpile each file as a separate module (similar to 'ts.transpileModule'). */

    /* Strict Type-Checking Options */
    "strict": true,                            /* Enable all strict type-checking options. */
    "noImplicitAny": true,                      /* Raise error on expressions and declarations with an implied 'any' type. */
    "strictNullChecks": true,              /* Enable strict null checks. */
    // "noImplicitThis": true,                /* Raise error on 'this' expressions with an implied 'any' type. */
    // "alwaysStrict": true,                  /* Parse in strict mode and emit "use strict" for each source file. */

    /* Additional Checks */
    // "noUnusedLocals": true,                /* Report errors on unused locals. */
    // "noUnusedParameters": true,            /* Report errors on unused parameters. */
    // "noImplicitReturns": true,             /* Report error when not all code paths in function return a value. */
    // "noFallthroughCasesInSwitch": true,    /* Report errors for fallthrough cases in switch statement. */

    /* Module Resolution Options */
    // "moduleResolution": "node",            /* Specify module resolution strategy: 'node' (Node.js) or 'classic' (TypeScript pre-1.6). */
    // "baseUrl": "./",                       /* Base directory to resolve non-absolute module names. */
    // "paths": {},                           /* A series of entries which re-map imports to lookup locations relative to the 'baseUrl'. */
    // "rootDirs": [],                        /* List of root folders whose combined content represents the structure of the project at runtime. */
    // "typeRoots": [],                       /* List of folders to include type definitions from. */
    // "types": [],                           /* Type declaration files to be included in compilation. */
    // "allowSyntheticDefaultImports": true,  /* Allow default imports from modules with no default export. This does not affect code emit, just typechecking. */

    /* Source Map Options */
    // "sourceRoot": "./",                    /* Specify the location where debugger should locate TypeScript files instead of source locations. */
    // "mapRoot": "./",                       /* Specify the location where debugger should locate map files instead of generated locations. */
    // "inlineSourceMap": true,               /* Emit a single file with source maps instead of having a separate file. */
    // "inlineSources": true,                 /* Emit the source alongside the sourcemaps within a single file; requires '--inlineSourceMap' or '--sourceMap' to be set. */

    /* Experimental Options */
    // "experimentalDecorators": true,        /* Enables experimental support for ES7 decorators. */
    // "emitDecoratorMetadata": true,         /* Enables experimental support for emitting type metadata for decorators. */
    "lib": [
      "dom",
      "es5",
      "es2015.promise"
    ]
  }
}

package.json

{
  "name": "TypescriptProject5",
  "version": "1.0.0",
  "description": "",
  "main": "index.js",
  "scripts": {
    "start": "webpack-dev-server",
    "build": "webpack --watch",
    "test": "echo \"Error: no test specified\" && exit 1"
  },
  "keywords": [],
  "author": "",
  "license": "ISC",
  "devDependencies": {
    "ts-loader": "^2.1.0",
    "tslint": "^5.4.2",
    "typescript": "^2.3.4",
    "webpack": "^2.6.1",
    "webpack-dev-server": "^2.4.5",
    "write-file-webpack-plugin": "^4.0.2"
  },
  "dependencies": {
    "es6-promise": "^4.1.0"
  }
}

Right now tslint complains about resolve, reject and res (expected arrow parameter to have a typedef)

Update #2 : This code does not give me any tslint or TS errors

const promise: Promise<number> = new Promise((resolve: (value?: {} | PromiseLike<{}> | undefined) => void, reject: (reason?: any) => void): void => {
    //the resolve / reject functions control the fate of the promise
    resolve(123);
});

//The promise fate can be subscribed to using .then (if resolved) or .catch (if rejected)
promise.then((res: number) => {
    console.log('I get called:', res === 123);      //I get called: true
});

Body:
This is trivial to test.

new Promise(function (res, rej) {
    console.log(res());
});

new Promise(function (res, rej) {
    console.log(rej());
});

They both return undefined.


问:
Not able to get text which is not inside any tag Using selenium
How can i get "File transfer overdue for 3PAR/INSERV/CZ3602WT5A" text using selenium webdriver. which is not inside any tag.
Not able to get text for an element using Selenium  How to get text of element that is not inside html tag using Selenium webdriver

```

HPE 3PAR StoreServ 8200 2N Fld Int Base - csi - File transfer overdue for 3PAR/INSERV/CZ3602WT5A

Case data updated: 2017-04-05_10.38

                    Product Number:

                    K2Q36A

                    Open Date:

                    2017-02-26 17:19:56.0

                    Serial Number:

                    CZ3602WT5A

                    Close Date:

                    2017-02-27 09:24:04.0

                    Product Description:

                    HPE 3PAR StoreServ 8200 2-node Field Integrated Storage Base

                    Days Open:

                    1

                    Customer:

                    EUSKO LEGEBILTZARRA PARLAMENTO VASCO

                    Case Status:

                    Closed

                    Country:

                    Spain

                    Any Onsite:

                     No

                    Warranty Applied:
                05R-Norml Contract

                    Multiple Visits:

                     No

                Repair Class:
Repair Class NA in SFDC
                    Number of Parts Used:

                    0

                Case Log

HPE 3PAR StoreServ 8200 2N Fld Int Base - csi - File transfer overdue for 3PAR/INSERV/CZ3602WT5A

                2017-02-26 17:19:56.0 -Sunday-  (Elapsed Time D: 0 / H: 0 / M:0)
                Issue
                By: carlos.taboada@hpe.com

File Transfer Overdue issue. Probably customer network or Service Processor Issue

                2017-02-26 17:19:56.003 -Sunday-  (Elapsed Time D: 0 / H: 0 / M:0)
                Additional Product Info
                By: carlos.taboada@hpe.com

ProductLine - 4A

FirmwareVer -

SoftwareVer -

OperatingSystemVer -

City - VITORIA-GASTEIZ

                2017-02-26 17:19:56.003 -Sunday-  (Elapsed Time D: 0 / H: 0 / M:0)
                Environment
                By: carlos.taboada@hpe.com

SW Version4.4.0.GA-30ModelVMware-Virtual-Platform

                2017-02-26 17:19:56.007 -Sunday-  (Elapsed Time D: 0 / H: 0 / M:0)
                Additional Case Info
                By: carlos.taboada@hpe.com

Origin - STaTS

RecordType - GSD CSC Case Closed

SupportType - Diagnosis (Level 1)

Severity - 3-NORMAL

Language - Spanish

ResolutionType - Remote Resolve

ResolutionCode - Resolved

ResolutionSubCode - HW Issue

NewInstall: No

InstallIssue:

ErrorCode -

Comments - IH 3PAR Aler SIS FOU

ResolutionCategory -

Outage - No

                2017-02-26 17:19:56.007 -Sunday-  (Elapsed Time D: 0 / H: 0 / M:0)
                Resolution
                By: carlos.taboada@hpe.com

Summary:

Details:

They had a blackout. everyhting it is OK. we can close the case.

                2017-02-26 17:19:56.007 -Sunday-  (Elapsed Time D: 0 / H: 0 / M:0)
                Causes
                By: carlos.taboada@hpe.com

FTO

                2017-02-26 17:19:56.01 -Sunday-  (Elapsed Time D: 0 / H: 0 / M:0)
                Warranty
                By: carlos.taboada@hpe.com

EntitleSummary - HPE Hardware Maintenance Onsite Support  4HR Response / 9X5; Global Coverage

ServicePortfolio - Contract

Response - 4HR

Coverage - 9x5

WarrantyExceptionDetail -

ExceptionReason -

ExceptionProcess -

                2017-02-26 17:19:56.01 -Sunday-  (Elapsed Time D: 0 / H: 0 / M:0)
                ExternalInfo
                By: carlos.taboada@hpe.com

File transfer overdue for 3PAR/INSERV/CZ3602WT5A

                2017-02-26 17:19:58.0 -Sunday-  (Elapsed Time D: 0 / H: 0 / M:0)
                Chatter
                By: cscapiuser@hpe.com

HPE Serial Number: CZ3602WT5A       HPE Product Name: K2Q36A       3PAR Serial Number: CZ3602WT5A

RAPDB Comments: --------

Analysis

--------

RAP History:

   In the last 30 days, 0 FTO RAPs have been processed

InServ vs SP FTO:

   The call home times are equal

InServ Connection:

   The files times are within 24 hours

SP Config:

   Port 5782 or 5783 is down: mgmt/cli connection is not up

Axeda Ping:

   The last Axeda connection was 1 Days, 7 Hours, 21 Minutes, 21 Seconds ago

Axeda Mute:

   This device is not muted

--------

                2017-02-26 23:29:51.0 -Sunday-  (Elapsed Time D: 0 / H: 6 / M:9)
                Email_text
                By: donot_contact_sfdc_automated_case_user@groups.ext.hpe.com

5002700000qDsziAAC_02s2700000Vt6TwAAJ_email.txt

                2017-02-26 23:31:57.0 -Sunday-  (Elapsed Time D: 0 / H: 6 / M:12)
                Plan of Action
                By: ajay.singh3@hpe.com

Subject - POA

Status - Completed

ActivityText - xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx

Plan of Action: Communicate below to the customer -

1.  Please verify if you can reach the SP from your internal network via http://SPIPDADDRESS and refer to the below link to verify if the SP is sending files home :

http://h20195.www2.hp.com/V2/GetDocument.aspx?docname=4AA5-1582ENW&cc=us&lc=en

If not, let us know a convenient date and time to setup a VR session and take a look at the SP.

2.  Patch update needed (P003) – please confirm if we can go ahead and deploy the patch on the SP. It is non-intrusive and can be performed anytime remotely or through HP Virtual Room. Ensure the ‘Serial Cable’ is not connected to the physical SP during the patch installation.

xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx

Onsite service required: No. this action can be performed remotely.

Special Instructions: For any further details on POA, please contact case owner or his team via chat or e-mail ftocore@hp.com.

After the POA is followed wait for an hour, then please verify the call home using the below steps :

1. Login to STATs and under Reports tab click on Transfer Status Report

2. Type/Paste the InServ serial under General keyword search and click Search.

3. If ‘no data found’ under results, issue is resolved.

3. If not, please get back to connectivity team for further POA.

NOTE: Before contacting FTO team in order to troubleshoot, please ensure customer is on the VR ready with putty session and Keyboard converted to English (US).

How to change Keyboard:

·         Click Start > type intl.cpl in start search box and press ENTER.

·         On the Keyboards and Language tab, click Change keyboards > Click ADD

·         Expand the language 'English (USA)' > Expand Keyboard > Select US-International.

·         In the Default input language list, click US-international and click OK 2 times.

**************** End of POA *****************

                2017-02-27 00:05:01.0 -Monday-  (Elapsed Time D: 0 / H: 6 / M:45)
                Chatter
                By: fernando.garzon@hpe.com

[DIAGNOSIS_QUALIFICATION] / [Non-Standard Diagnosis]

3PAR 8000 CSI Service Delivery Instructions Attention! This product is a 2 node system which is eligible for CSI (Customer Self install) and also eligible for remote and onsite installation support via CSC. Please verify with the customer if this is a new system/installation and provide up to 1 hour installation support. Please follow the steps below: 1. Entitle the case on the warranty/SAID/Care Pack of the product 2. Put CSI in the case title 3. Advise the customer that although it is a CSI, CSC is able to offer 1 hour of remote support to help resolve the installation issue. 4. If CSC manage to resolve the issue, close the case as usual. 5. If no resolution is achieved in the 1 hour of remote support, offer to connect the customer with Installation Services to purchase Installation Support. a. If the customer accepts please do the following: For all regions 1. Advise the customer to contact local sales for purchasing I&S Care Pack 2. Submit One Lead - https://ent301.sharepoint.hp.com/teams/Global-ONELead/SitePages/Default.aspx and tell the customer to expect a call from the sales team b. If the customer doesn’t accept the offer, entitle the case according the internal gratis process, offer to send a CE Onsite as an exception and dispatch the case to your local country Queue For all regions Location code: 52JGE03700001Y00 Authorizing Employee: Sandra.s@hpe.comless

                2017-02-27 09:20:01.0 -Monday-  (Elapsed Time D: 0 / H: 16 / M:0)
                Troubleshooting
                By: carlos.taboada@hpe.com

Subject - Troubleshooting

Status - Completed

ActivityText - they had a blackout and the already up the machines. so we can close the case.

                2017-02-27 09:20:52.0 -Monday-  (Elapsed Time D: 0 / H: 16 / M:0)
                Plan of Action
                By: carlos.taboada@hpe.com

Subject - POA

Status - Completed

ActivityText - - close the case. they are agree.

                2017-02-27 09:24:09.0 -Monday-  (Elapsed Time D: 0 / H: 16 / M:4)
                Closing your Case
                By: carlos.taboada@hpe.com

Subject - Closing your Case

Status - Completed

ActivityText -

                2017-02-27 09:24:10.0 -Monday-  (Elapsed Time D: 0 / H: 16 / M:4)
                Email_text
                By: donot_contact_sfdc_automated_case_user@groups.ext.hpe.com

5002700000qDsziAAC_02s2700000VtM75AAF_email.txt

Email call technicians: Click Here

This case file was generated by TextScanner2DB version 2.03

```

答:
It looks like your text is in an
.

Try (C# code, Java will be similar):

```<code>string h2text = driver.FindElement(By.CssSelector("body > h2")).Text;
</code>```

The value of h2text should end up being:

"HPE 3PAR StoreServ 8200 2N Fld Int Base - csi - File transfer overdue for 3PAR/INSERV/CZ3602WT5A"

I also see (what you are likely asking about) a  with the text in it. It looks like the  element is the container. That is unfortunate because calling .Text on the body would return all such text. It would be up to you to parse that string.

Body:
How can i get "File transfer overdue for 3PAR/INSERV/CZ3602WT5A" text using selenium webdriver. which is not inside any tag.
Not able to get text for an element using Selenium  How to get text of element that is not inside html tag using Selenium webdriver

HPE 3PAR StoreServ 8200 2N Fld Int Base - csi - File transfer overdue for 3PAR/INSERV/CZ3602WT5A

Case data updated: 2017-04-05_10.38

                    Product Number:

                    K2Q36A

                    Open Date:

                    2017-02-26 17:19:56.0

                    Serial Number:

                    CZ3602WT5A

                    Close Date:

                    2017-02-27 09:24:04.0

                    Product Description:

                    HPE 3PAR StoreServ 8200 2-node Field Integrated Storage Base

                    Days Open:

                    1

                    Customer:

                    EUSKO LEGEBILTZARRA PARLAMENTO VASCO

                    Case Status:

                    Closed

                    Country:

                    Spain

                    Any Onsite:

                     No

                    Warranty Applied:
                05R-Norml Contract

                    Multiple Visits:

                     No

                Repair Class:
Repair Class NA in SFDC
                    Number of Parts Used:

                    0

                Case Log

HPE 3PAR StoreServ 8200 2N Fld Int Base - csi - File transfer overdue for 3PAR/INSERV/CZ3602WT5A

                2017-02-26 17:19:56.0 -Sunday-  (Elapsed Time D: 0 / H: 0 / M:0)
                Issue
                By: carlos.taboada@hpe.com

File Transfer Overdue issue. Probably customer network or Service Processor Issue

                2017-02-26 17:19:56.003 -Sunday-  (Elapsed Time D: 0 / H: 0 / M:0)
                Additional Product Info
                By: carlos.taboada@hpe.com

ProductLine - 4A

FirmwareVer -

SoftwareVer -

OperatingSystemVer -

City - VITORIA-GASTEIZ

                2017-02-26 17:19:56.003 -Sunday-  (Elapsed Time D: 0 / H: 0 / M:0)
                Environment
                By: carlos.taboada@hpe.com

SW Version4.4.0.GA-30ModelVMware-Virtual-Platform

                2017-02-26 17:19:56.007 -Sunday-  (Elapsed Time D: 0 / H: 0 / M:0)
                Additional Case Info
                By: carlos.taboada@hpe.com

Origin - STaTS

RecordType - GSD CSC Case Closed

SupportType - Diagnosis (Level 1)

Severity - 3-NORMAL

Language - Spanish

ResolutionType - Remote Resolve

ResolutionCode - Resolved

ResolutionSubCode - HW Issue

NewInstall: No

InstallIssue:

ErrorCode -

Comments - IH 3PAR Aler SIS FOU

ResolutionCategory -

Outage - No

                2017-02-26 17:19:56.007 -Sunday-  (Elapsed Time D: 0 / H: 0 / M:0)
                Resolution
                By: carlos.taboada@hpe.com

Summary:

Details:

They had a blackout. everyhting it is OK. we can close the case.

                2017-02-26 17:19:56.007 -Sunday-  (Elapsed Time D: 0 / H: 0 / M:0)
                Causes
                By: carlos.taboada@hpe.com

FTO

                2017-02-26 17:19:56.01 -Sunday-  (Elapsed Time D: 0 / H: 0 / M:0)
                Warranty
                By: carlos.taboada@hpe.com

EntitleSummary - HPE Hardware Maintenance Onsite Support  4HR Response / 9X5; Global Coverage

ServicePortfolio - Contract

Response - 4HR

Coverage - 9x5

WarrantyExceptionDetail -

ExceptionReason -

ExceptionProcess -

                2017-02-26 17:19:56.01 -Sunday-  (Elapsed Time D: 0 / H: 0 / M:0)
                ExternalInfo
                By: carlos.taboada@hpe.com

File transfer overdue for 3PAR/INSERV/CZ3602WT5A

                2017-02-26 17:19:58.0 -Sunday-  (Elapsed Time D: 0 / H: 0 / M:0)
                Chatter
                By: cscapiuser@hpe.com

HPE Serial Number: CZ3602WT5A       HPE Product Name: K2Q36A       3PAR Serial Number: CZ3602WT5A

RAPDB Comments: --------

Analysis

--------

RAP History:

   In the last 30 days, 0 FTO RAPs have been processed

InServ vs SP FTO:

   The call home times are equal

InServ Connection:

   The files times are within 24 hours

SP Config:

   Port 5782 or 5783 is down: mgmt/cli connection is not up

Axeda Ping:

   The last Axeda connection was 1 Days, 7 Hours, 21 Minutes, 21 Seconds ago

Axeda Mute:

   This device is not muted

--------

                2017-02-26 23:29:51.0 -Sunday-  (Elapsed Time D: 0 / H: 6 / M:9)
                Email_text
                By: donot_contact_sfdc_automated_case_user@groups.ext.hpe.com

5002700000qDsziAAC_02s2700000Vt6TwAAJ_email.txt

                2017-02-26 23:31:57.0 -Sunday-  (Elapsed Time D: 0 / H: 6 / M:12)
                Plan of Action
                By: ajay.singh3@hpe.com

Subject - POA

Status - Completed

ActivityText - xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx

Plan of Action: Communicate below to the customer -

1.  Please verify if you can reach the SP from your internal network via http://SPIPDADDRESS and refer to the below link to verify if the SP is sending files home :

http://h20195.www2.hp.com/V2/GetDocument.aspx?docname=4AA5-1582ENW&cc=us&lc=en

If not, let us know a convenient date and time to setup a VR session and take a look at the SP.

2.  Patch update needed (P003) – please confirm if we can go ahead and deploy the patch on the SP. It is non-intrusive and can be performed anytime remotely or through HP Virtual Room. Ensure the ‘Serial Cable’ is not connected to the physical SP during the patch installation.

xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx

Onsite service required: No. this action can be performed remotely.

Special Instructions: For any further details on POA, please contact case owner or his team via chat or e-mail ftocore@hp.com.

After the POA is followed wait for an hour, then please verify the call home using the below steps :

1. Login to STATs and under Reports tab click on Transfer Status Report

2. Type/Paste the InServ serial under General keyword search and click Search.

3. If ‘no data found’ under results, issue is resolved.

3. If not, please get back to connectivity team for further POA.

NOTE: Before contacting FTO team in order to troubleshoot, please ensure customer is on the VR ready with putty session and Keyboard converted to English (US).

How to change Keyboard:

·         Click Start > type intl.cpl in start search box and press ENTER.

·         On the Keyboards and Language tab, click Change keyboards > Click ADD

·         Expand the language 'English (USA)' > Expand Keyboard > Select US-International.

·         In the Default input language list, click US-international and click OK 2 times.

**************** End of POA *****************

                2017-02-27 00:05:01.0 -Monday-  (Elapsed Time D: 0 / H: 6 / M:45)
                Chatter
                By: fernando.garzon@hpe.com

[DIAGNOSIS_QUALIFICATION] / [Non-Standard Diagnosis]

3PAR 8000 CSI Service Delivery Instructions Attention! This product is a 2 node system which is eligible for CSI (Customer Self install) and also eligible for remote and onsite installation support via CSC. Please verify with the customer if this is a new system/installation and provide up to 1 hour installation support. Please follow the steps below: 1. Entitle the case on the warranty/SAID/Care Pack of the product 2. Put CSI in the case title 3. Advise the customer that although it is a CSI, CSC is able to offer 1 hour of remote support to help resolve the installation issue. 4. If CSC manage to resolve the issue, close the case as usual. 5. If no resolution is achieved in the 1 hour of remote support, offer to connect the customer with Installation Services to purchase Installation Support. a. If the customer accepts please do the following: For all regions 1. Advise the customer to contact local sales for purchasing I&S Care Pack 2. Submit One Lead - https://ent301.sharepoint.hp.com/teams/Global-ONELead/SitePages/Default.aspx and tell the customer to expect a call from the sales team b. If the customer doesn’t accept the offer, entitle the case according the internal gratis process, offer to send a CE Onsite as an exception and dispatch the case to your local country Queue For all regions Location code: 52JGE03700001Y00 Authorizing Employee: Sandra.s@hpe.comless

                2017-02-27 09:20:01.0 -Monday-  (Elapsed Time D: 0 / H: 16 / M:0)
                Troubleshooting
                By: carlos.taboada@hpe.com

Subject - Troubleshooting

Status - Completed

ActivityText - they had a blackout and the already up the machines. so we can close the case.

                2017-02-27 09:20:52.0 -Monday-  (Elapsed Time D: 0 / H: 16 / M:0)
                Plan of Action
                By: carlos.taboada@hpe.com

Subject - POA

Status - Completed

ActivityText - - close the case. they are agree.

                2017-02-27 09:24:09.0 -Monday-  (Elapsed Time D: 0 / H: 16 / M:4)
                Closing your Case
                By: carlos.taboada@hpe.com

Subject - Closing your Case

Status - Completed

ActivityText -

                2017-02-27 09:24:10.0 -Monday-  (Elapsed Time D: 0 / H: 16 / M:4)
                Email_text
                By: donot_contact_sfdc_automated_case_user@groups.ext.hpe.com

5002700000qDsziAAC_02s2700000VtM75AAF_email.txt

Email call technicians: Click Here

This case file was generated by TextScanner2DB version 2.03

Body:
It looks like your text is in an <h2>.

Try (C# code, Java will be similar):

string h2text = driver.FindElement(By.CssSelector("body > h2")).Text;

The value of h2text should end up being:

"HPE 3PAR StoreServ 8200 2N Fld Int Base - csi - File transfer overdue for 3PAR/INSERV/CZ3602WT5A"

I also see (what you are likely asking about) a <!-- Record Header --> with the text in it. It looks like the <body> element is the container. That is unfortunate because calling .Text on the body would return all such text. It would be up to you to parse that string.


问:
Typoscript: Constants in value section
I've a object with some HTML code. I want to use a constant inside. My code is the following:

```<code>15 = TEXT
15 {
    data = getenv : TYPO3_SITE_URL
    wrap (
        <a href="https://www.xing.com/spi/shares/new?url={data}" target="_blank"><div class="c-menu-share__item social-xing"></div></a>

        <a href="https://www.linkedin.com/shareArticle?mini=true&url={data}" target="_blank"><div class="c-menu-share__item social-linkedin"></div></a>

        <a href="https://www.facebook.com/sharer/sharer.php?u={data}" target="_blank"><div class="c-menu-share__item social-facebook"></div></a>

        <a href="mailto:?body={data}" target="_blank"><div class="c-menu-share__item social-email"></div></a>
    )
}
15.outerWrap = <div class="c-menu-share">|</div>
</code>```

That doesn't work. Can anybody help me?
Thanks in advance!

答:
You can´t use 'data' as a variable, but you can get your environment variable via {getIndpEnv : TYPO3_SITE_URL} (or {getIndpEnv : TYPO3_REQUEST_URL} if you want the url of the current page) directly. Try this:

```<code>15 = TEXT
15.value (
    <a href="https://www.xing.com/spi/shares/new?url={getIndpEnv : TYPO3_SITE_URL} " target="_blank"><div class="c-menu-share__item social-xing"></div></a>
    <a href="https://www.linkedin.com/shareArticle?mini=true&url={getIndpEnv : TYPO3_SITE_URL} " target="_blank"><div class="c-menu-share__item social-linkedin"></div></a>
    <a href="https://www.facebook.com/sharer/sharer.php?u={getIndpEnv : TYPO3_SITE_URL} " target="_blank"><div class="c-menu-share__item social-facebook"></div></a>
    <a href="mailto:?body={getIndpEnv : TYPO3_SITE_URL} " target="_blank"><div class="c-menu-share__item social-email"></div></a>
)
15.insertData = 1
</code>```

Title: Typoscript: Constants in value section

Body:
I've a object with some HTML code. I want to use a constant inside. My code is the following:

15 = TEXT
15 {
    data = getenv : TYPO3_SITE_URL
    wrap (

    )
}
15.outerWrap =
|

That doesn't work. Can anybody help me?
Thanks in advance!

Body:
You can´t use 'data' as a variable, but you can get your environment variable via {getIndpEnv : TYPO3_SITE_URL} (or {getIndpEnv : TYPO3_REQUEST_URL} if you want the url of the current page) directly. Try this:

15 = TEXT
15.value (
    <a href="https://www.xing.com/spi/shares/new?url={getIndpEnv : TYPO3_SITE_URL} " target="_blank"><div class="c-menu-share__item social-xing"></div></a>
    <a href="https://www.linkedin.com/shareArticle?mini=true&url={getIndpEnv : TYPO3_SITE_URL} " target="_blank"><div class="c-menu-share__item social-linkedin"></div></a>
    <a href="https://www.facebook.com/sharer/sharer.php?u={getIndpEnv : TYPO3_SITE_URL} " target="_blank"><div class="c-menu-share__item social-facebook"></div></a>
    <a href="mailto:?body={getIndpEnv : TYPO3_SITE_URL} " target="_blank"><div class="c-menu-share__item social-email"></div></a>
)
15.insertData = 1


问:
IE 11 failed to create file object from byte array in Angular 2
Can anybody tell me why IE11 is throwing error at the last line - </p>

```<code>this.document = this.control.value;
  const bytes =
this.documentService.base64toBytes(this.document.documentBlob.documentData,
       this.document.documentDataFormat);
const file = new File(bytes, this.document.documentName, { type:
       this.document.documentDataFormat });
</code>```

<p>This is working in both Chrome and Firefox.IE throws object error - </p>

```<code>Object doesn't support this action.
</code>```

答:
As IE does not support constructor of File API, I have come up with the following workaround. Hope this helps to others in future - </p>

```<code>const bytes = this.documentService.base64toBytes(this.document.documentBlob.documentData, this.document.documentDataFormat);
let file: File;
try {
  file = new File(bytes, this.document.documentName, { type: this.document.documentDataFormat });

  if (this.uploader.isFile(file)) {
    this.uploader.addToQueue([file]);
  }
} catch (err) { // Workaround for IE 11
  const blob = this.documentService.base64ToBlob(this.document.documentBlob.documentData,
    this.document.documentDataFormat);
  file = this.documentService.blobToFile(blob, this.document.documentName);
  this.uploader.addToQueue([file]);
</code>```

Body:
Can anybody tell me why IE11 is throwing error at the last line -

this.document = this.control.value;
  const bytes =
this.documentService.base64toBytes(this.document.documentBlob.documentData,
       this.document.documentDataFormat);
const file = new File(bytes, this.document.documentName, { type:
       this.document.documentDataFormat });

This is working in both Chrome and Firefox.IE throws object error -

Object doesn't support this action.

Body:
As IE does not support constructor of File API, I have come up with the following workaround. Hope this helps to others in future -

const bytes = this.documentService.base64toBytes(this.document.documentBlob.documentData, this.document.documentDataFormat);
let file: File;
try {
  file = new File(bytes, this.document.documentName, { type: this.document.documentDataFormat });

  if (this.uploader.isFile(file)) {
    this.uploader.addToQueue([file]);
  }
} catch (err) { // Workaround for IE 11
  const blob = this.documentService.base64ToBlob(this.document.documentBlob.documentData,
    this.document.documentDataFormat);
  file = this.documentService.blobToFile(blob, this.document.documentName);
  this.uploader.addToQueue([file]);


问:
display php array in javascript
I like to display php array in javascript, but in specific  element with id.
below is my code which shows what I want to do.

```<code><?php function ogolne_informacje(){
    global $mypod;?>
        <strong><?php echo 'Pokój: '?></strong><?php echo $mypod->display('room')."<br />";?>
        <strong><?php echo 'Email: '?></strong><a href="mailto:<?php echo $mypod->display('user_email') ?>"><?php echo $mypod->display('user_email')."<br />";?></a>
        <strong><?php echo 'Telefon: '?></strong><?php echo $mypod->display('phone')."<br />"; }?>

<?php $i =0;
while ( $mypod->fetch() ) :{
    ob_start();
    ogolne_informacje();
    $output[$i] = ob_get_clean();
    $i++;
} endwhile;?>

<div id="test"></div>
<script>
var out = <?php echo $output; ?>;
    $(document).ready(function () {
    $('#test').html(out.toString());
});
</script>
</code>```

How can I do that?
Thanks!

答:
You can't loop like that, you need to loop the PHP array and push into javascript array:</p>

```<code><script type="text/javascript" language="javascript">
    var pausecontent = new Array();
    <?php while ( $mypod->fetch() ) :{
          ob_start();
          ogolne_informacje();
    ?>
        pausecontent.push('<?php echo ob_get_clean(); ?>');
    <?php } ?>
</script>
</code>```

Title: display php array in javascript

Body:
I like to display php array in javascript, but in specific  element with id.
below is my code which shows what I want to do.

<?php function ogolne_informacje(){
    global $mypod;?>
        <?php echo 'Pokój: '?><?php echo $mypod->display('room')."
";?>
        <?php echo 'Email: '?><a href="mailto:<?php echo $mypod->display('user_email') ?>"><?php echo $mypod->display('user_email')."
";?>
        <?php echo 'Telefon: '?><?php echo $mypod->display('phone')."
"; }?>

<?php $i =0;
while ( $mypod->fetch() ) :{
    ob_start();
    ogolne_informacje();
    $output[$i] = ob_get_clean();
    $i++;
} endwhile;?>

How can I do that?
Thanks!

Body:
You can't loop like that, you need to loop the PHP array and push into javascript array:

<script type="text/javascript" language="javascript">
    var pausecontent = new Array();
    <?php while ( $mypod->fetch() ) :{
          ob_start();
          ogolne_informacje();
    ?>
        pausecontent.push('<?php echo ob_get_clean(); ?>');
    <?php } ?>
</script>


问:
Scrollable table having a redraw issue. Doesnt seem to be clearing
I have a scrollable table.
In each cell I draw 3 UILabels. The first few cells draw ok. But as I scroll down the table the UILabels seems to be drawing over previous UILabels. Its like the Labels in the cell have an old label already there that was cleared. I could probably fix this by drawing a background color over the whole cell each redraw, but that still doesn't explain this strange problem and why its happening.

Anybody know why this occurs and what a solution might be?

```<code>- (UITableViewCell *)tableView:(UITableView *)tableView
cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *CellIdentifier = @"Cell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil)
{
    cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault
reuseIdentifier:CellIdentifier] autorelease];
}

Match *aMatch = [appDelegate.matchScoresArray objectAtIndex:indexPath.row];

UILabel * teamName1Label = [[UILabel alloc]initWithFrame:CGRectMake(5,5, 100, 20)];
teamName1Label.textAlignment = UITextAlignmentCenter;
teamName1Label.textColor =  [UIColor redColor];
teamName1Label.backgroundColor = [UIColor clearColor];
teamName1Label.text = aMatch.teamName1;
[cell addSubview:teamName1Label];

UILabel *teamVersusLabel = [[UILabel alloc]initWithFrame:CGRectMake(115,5, 40, 20)];
teamVersusLabel.textAlignment = UITextAlignmentCenter;
teamVersusLabel.textColor =  [UIColor redColor];
teamVersusLabel.backgroundColor = [UIColor clearColor];
teamVersusLabel.text = @"V";
[cell addSubview:teamVersusLabel];

UILabel *teamName2Label = [[UILabel alloc]initWithFrame:CGRectMake(155,5, 100, 20)];
teamName2Label.textAlignment = UITextAlignmentCenter;
teamName2Label.textColor =  [UIColor redColor];
teamName2Label.backgroundColor = [UIColor clearColor];
teamName2Label.text = aMatch.teamName2;
[cell addSubview:teamName2Label];

return cell;
}
</code>```

Many Thanks
-Code

答:
This is a cell re-use issue.  The code is adding the labels to the cell every time cellForRowAtIndexPath is called (even if cell is not nil).

When you scroll, a previous cell that already has the labels is loaded and then the code adds new labels over the old ones.

Only create and add the labels to the cell in the if (cell == nil) section.  When creating the labels, set tags on the labels.

Then outside the if, retrieve the labels using their tag using viewWithTag and set their text.

ContentLicense: CC BY-SA 2.5

Body:
I have a scrollable table.
In each cell I draw 3 UILabels. The first few cells draw ok. But as I scroll down the table the UILabels seems to be drawing over previous UILabels. Its like the Labels in the cell have an old label already there that was cleared. I could probably fix this by drawing a background color over the whole cell each redraw, but that still doesn't explain this strange problem and why its happening.

Anybody know why this occurs and what a solution might be?

- (UITableViewCell *)tableView:(UITableView *)tableView
cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *CellIdentifier = @"Cell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil)
{
    cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault
reuseIdentifier:CellIdentifier] autorelease];
}

Match *aMatch = [appDelegate.matchScoresArray objectAtIndex:indexPath.row];

UILabel * teamName1Label = [[UILabel alloc]initWithFrame:CGRectMake(5,5, 100, 20)];
teamName1Label.textAlignment = UITextAlignmentCenter;
teamName1Label.textColor =  [UIColor redColor];
teamName1Label.backgroundColor = [UIColor clearColor];
teamName1Label.text = aMatch.teamName1;
[cell addSubview:teamName1Label];

UILabel *teamVersusLabel = [[UILabel alloc]initWithFrame:CGRectMake(115,5, 40, 20)];
teamVersusLabel.textAlignment = UITextAlignmentCenter;
teamVersusLabel.textColor =  [UIColor redColor];
teamVersusLabel.backgroundColor = [UIColor clearColor];
teamVersusLabel.text = @"V";
[cell addSubview:teamVersusLabel];

UILabel *teamName2Label = [[UILabel alloc]initWithFrame:CGRectMake(155,5, 100, 20)];
teamName2Label.textAlignment = UITextAlignmentCenter;
teamName2Label.textColor =  [UIColor redColor];
teamName2Label.backgroundColor = [UIColor clearColor];
teamName2Label.text = aMatch.teamName2;
[cell addSubview:teamName2Label];

return cell;
}

Many Thanks
-Code