问:
Why can't I get separate documents in my xpages repeat control?
I've done this before for other projects, but can't seem to get this to work this time.

I have a repeat control that returns a list of several unids.  A panel within the repeat is bound to a NotesDocument which opens the document based on each unid.  ignoreRequestParams=true on the panel.  Simple enough.  Except, it doesn't work.

```<code><xp:panel id="panelDetail">
    <xp:this.data>
        <xp:dominoDocument var="detdoc"
            formName="QuoteDetail" documentId="#{javascript:detdata}"
            ignoreRequestParams="true" action="openDocument">
        </xp:dominoDocument>
    </xp:this.data>
</code>```

where detdata is the var from the parent repeat control (the unid).

One of my links within the panel checks to see if my document (detdoc) is editable, however, this is the error I get.

```<code>Error calling method 'isEditable()' on an object of type 'lotus.domino.local.Document [Static Java Interface Wrapper, lotus.domino.local.Document: lotus.domino.Document]'
</code>```

what gives?

I have several edit boxes in the panel that are bound to fields in the detdoc and they appear to show correctly - each row shows different values, but my computed fields that use detdoc.getItemValueString("fieldname") all show the value from the first document.  ???

pic of my repeat

I've checked the properties and compared it to a previous working project and just can't put my finger on my problem here.  Can someone point me in the right direction?

答:
I found the solution.  My repeat control pulled unids from documents in a view.  The view used depended on a combobox above the repeat, which allowed the user to filter which entries they wanted to see.  In my formula for the combobox choices, I used

var detdoc = ventry.getDocument();
var seats = detdoc.getItemValueString("SeatVars");
etc

Apparently, this usage carried over into the panel below it, so it couldn't resolve this detdoc assignment and the "detdoc" I used for the panel dominoDocument data source.  I changed the combobox to use "doc" instead of "detdoc" and now my data source "detdoc" is correctly being found.

Guess I need to be a little less specific in my formulas.

Thank you for your responses - you prompted me to find the answer, and sometimes, that's all I need... just a different set of eyes and a different viewpoint.  Thank you again.

EDIT:
Sorry, progress made, but still not completely solved.
In my panel that has detdoc defined as the datasource, I have another repeat control that displays dynamically bound fields.  This means that the repeat must be defined with "Create Controls at Page Creation" checked.  However, it appears that this repeat is trying to render prior to the encompassing panel being bound to detdoc, because my repeat control binding formula reports "detdoc not found".  How can I use dynamic fields in my repeat when it doesn't recognize the detdoc at rendering?

Body:
I've done this before for other projects, but can't seem to get this to work this time.

I have a repeat control that returns a list of several unids.  A panel within the repeat is bound to a NotesDocument which opens the document based on each unid.  ignoreRequestParams=true on the panel.  Simple enough.  Except, it doesn't work.

<xp:panel id="panelDetail">
    <xp:this.data>
        <xp:dominoDocument var="detdoc"
            formName="QuoteDetail" documentId="#{javascript:detdata}"
            ignoreRequestParams="true" action="openDocument">
        </xp:dominoDocument>
    </xp:this.data>

where detdata is the var from the parent repeat control (the unid).

One of my links within the panel checks to see if my document (detdoc) is editable, however, this is the error I get.

Error calling method 'isEditable()' on an object of type 'lotus.domino.local.Document [Static Java Interface Wrapper, lotus.domino.local.Document: lotus.domino.Document]'

what gives?

I have several edit boxes in the panel that are bound to fields in the detdoc and they appear to show correctly - each row shows different values, but my computed fields that use detdoc.getItemValueString("fieldname") all show the value from the first document.  ???

pic of my repeat

I've checked the properties and compared it to a previous working project and just can't put my finger on my problem here.  Can someone point me in the right direction?


来源: stackexchange

问:
Cursors with LOOP
Sorry for the huge code. All I am trying to do is increment the variable YM1 (201702, 201703, 201704) by one month, execute the SQL statement and display the result using CURSOR.

CURRENT BEHAVIOR: The YM1 variable is not incremented. The code executes but always uses YM1 = '201702'.

```<code>YEAR_MONTH 201701 201702 0
YEAR_MONTH 201701 201703 0
YEAR_MONTH 201701 201704 0
</code>```

EXPECTED RESULT:

```<code>YEAR_MONTH 201701 201702 0
YEAR_MONTH 201701 201703 10
YEAR_MONTH 201701 201704 20
</code>```

Please let me know what I am missing. Breaking my head. Thanks a lot for the time.

```<code>set serveroutput on

DECLARE
    YM   VARCHAR2(10) := '201701';
    YM1  VARCHAR2(10) := '201702';
    row1 number := 0;

    CURSOR counts is
        SELECT COUNT(*)
        FROM   **table1 a**
        WHERE  a.year_month = YM
        AND    EXISTS
               ( SELECT 'Y'
                 FROM   **table2 b**
                 WHERE  a.id = b.id
                 AND    b.year_month = YM1 );
BEGIN
    OPEN counts;
    LOOP
        FETCH counts INTO row1;
        dbms_output.put_line('YEAR_MONTH '||YM||' '||YM1||' '||row1);
        YM1 := TO_CHAR(ADD_MONTHS(TO_DATE(YM1,'YYYY-MM'), +1), 'YYYYMM');
        EXIT WHEN YM1 > '201704'
    END LOOP;
    CLOSE counts;
END;
/
</code>```

答:
There is no increment happening as part  of the loop so it is always the same.
I am not sure if you are assuming this as the logic to increment YM1 value but it will never do that.
    ADD_MONTHS(TO_DATE(YM1,'YYYY-MM'), +1)

And are you trying to increment YM? Try increment with the below statement for YM1
YM1 := TO_CHAR(ADD_MONTHS(TO_DATE(YM1,'YYYY-MM'), +1), 'YYYYMM');

Editing to provide you the output..

```<code>set serveroutput on
DECLARE
YM VARCHAR2(10) := '201701';
YM1 VARCHAR2(10) := '201702';
BEGIN
 dbms_output.put_line('           Timing        YM       YM1');
 dbms_output.put_line('Before Increment'||YM||' '||YM1);
 LOOP
   YM1 := TO_CHAR(ADD_MONTHS(TO_DATE(YM1,'YYYY-MM'), +1), 'YYYYMM');
   dbms_output.put_line('After Increment '||YM||' '||YM1);
   EXIT WHEN YM1 > '201704';
 END LOOP;
END;
/

Timing        YM       YM1
Before Increment201701 201702
After Increment 201701 201703
After Increment 201701 201704
After Increment 201701 201705

PL/SQL procedure successfully completed.
</code>```

I just executed removing the tables and cursor..

ContentLicense: CC BY-SA 3.0

Title: Cursors with LOOP

Body:
Sorry for the huge code. All I am trying to do is increment the variable YM1 (201702, 201703, 201704) by one month, execute the SQL statement and display the result using CURSOR.

CURRENT BEHAVIOR: The YM1 variable is not incremented. The code executes but always uses YM1 = '201702'.

YEAR_MONTH 201701 201702 0
YEAR_MONTH 201701 201703 0
YEAR_MONTH 201701 201704 0

EXPECTED RESULT:

YEAR_MONTH 201701 201702 0
YEAR_MONTH 201701 201703 10
YEAR_MONTH 201701 201704 20

Please let me know what I am missing. Breaking my head. Thanks a lot for the time.

set serveroutput on

DECLARE
    YM   VARCHAR2(10) := '201701';
    YM1  VARCHAR2(10) := '201702';
    row1 number := 0;

    CURSOR counts is
        SELECT COUNT(*)
        FROM   **table1 a**
        WHERE  a.year_month = YM
        AND    EXISTS
               ( SELECT 'Y'
                 FROM   **table2 b**
                 WHERE  a.id = b.id
                 AND    b.year_month = YM1 );
BEGIN
    OPEN counts;
    LOOP
        FETCH counts INTO row1;
        dbms_output.put_line('YEAR_MONTH '||YM||' '||YM1||' '||row1);
        YM1 := TO_CHAR(ADD_MONTHS(TO_DATE(YM1,'YYYY-MM'), +1), 'YYYYMM');
        EXIT WHEN YM1 > '201704'
    END LOOP;
    CLOSE counts;
END;
/

Body:
There is no increment happening as part  of the loop so it is always the same.
I am not sure if you are assuming this as the logic to increment YM1 value but it will never do that.
    ADD_MONTHS(TO_DATE(YM1,'YYYY-MM'), +1)

And are you trying to increment YM? Try increment with the below statement for YM1
YM1 := TO_CHAR(ADD_MONTHS(TO_DATE(YM1,'YYYY-MM'), +1), 'YYYYMM');

Editing to provide you the output..

set serveroutput on
DECLARE
YM VARCHAR2(10) := '201701';
YM1 VARCHAR2(10) := '201702';
BEGIN
 dbms_output.put_line('           Timing        YM       YM1');
 dbms_output.put_line('Before Increment'||YM||' '||YM1);
 LOOP
   YM1 := TO_CHAR(ADD_MONTHS(TO_DATE(YM1,'YYYY-MM'), +1), 'YYYYMM');
   dbms_output.put_line('After Increment '||YM||' '||YM1);
   EXIT WHEN YM1 > '201704';
 END LOOP;
END;
/

Timing        YM       YM1
Before Increment201701 201702
After Increment 201701 201703
After Increment 201701 201704
After Increment 201701 201705

PL/SQL procedure successfully completed.

I just executed removing the tables and cursor..


问:
Configure cloudwatch -> elastic search through java code
If you look at the following link: http://docs.aws.amazon.com/AmazonCloudWatch/latest/logs/CWL_ES_Stream.html, there is a mechanism to associate a log group with an elastic search domain. Do you know this can be done via the java aws sdk so that it can be automated in a running application?</p>

答:
Assuming the EC domain is already created.

Create IAM role that allows Cloudwatch logs access to ES.

```<code>{
"Version": "2012-10-17",

"Statement": [
    {
        "Action": [
            "es:*"
        ],
        "Effect": "Allow",
        "Resource": "arn:aws:es:us-west-2:123456789012:domain/streaming-logs/*"
    }
  ]

}
</code>```

Create the log group

Create the Subscription filter

Body:
Assuming the EC domain is already created.

Create IAM role that allows Cloudwatch logs access to ES.

{
"Version": "2012-10-17",

"Statement": [
    {
        "Action": [
            "es:*"
        ],
        "Effect": "Allow",
        "Resource": "arn:aws:es:us-west-2:123456789012:domain/streaming-logs/*"
    }
  ]

}

Create the log group

Create the Subscription filter


问:
How to shift a value when using SQL in python
Picture: Misaligned columns:

Please refer to the picture linked above. I have an email report showing negative values with parentheses around them. I need to make it do that the last digit in each number lines up with each other. The values are being printing by using for-loops and if-statements when running SQL statements. The values are printed as they run through the SQL statements.

How do I get the positive values to shift once to the left to align with the last digit of the numbers in parentheses?

Here are the for loops that print the columns in the report:

```<code>m1_total=0
m3_total=0
m6_total=0
m12_total=0

for line in curs:
    if (line[1]==0) or (line[1]==None): #skip if the M1 is 0
        continue

    m1=0
    m3=0
    m6=0
    m12=0
    if line[1]>0:
        m1=line[1]
    if line[2]>0:
        m3=round(line[2]/3)
    if line[3]>0:
        m6=round(line[3]/6)
    if line[4]>0:
        m12=round(line[4]/12)
    mc3=0
    mc6=0
    mc12=0
    if m3 > 0:
        mc3=round((m1/m3)*100-100,2)
    if m6>0:
        mc6=round((m3/m6)*100-100,2)
    if m12 > 0:
        mc12=round((m6/m12)*100-100,2)

    outStr+=str(line[0]).ljust(13,'.')+round_dolls(m1,9)+round_dolls(m3,9)+round_dolls(m6,9)+round_dolls(m12,9)
    outStr+=round_dolls(mc3,14,'d')+round_dolls(mc6,9,'d')+round_dolls(mc12,9,'d') + '<br>'
    m1_total+=m1
    m3_total+=m3
    m6_total+=m6
    m12_total+=m12
    mc3_total=0
    mc6_total=0
    mc12_total=0
    if m3_total > 0:
        mc3_total=round((m1_total/m3_total)*100-100,2)
    if m6_total>0:
        mc6_total=round((m3_total/m6_total)*100-100,2)
    if m12_total > 0:
        mc12_total=round((m6_total/m12_total)*100-100,2)

    if line[-1] != ')':
        str(m12) = str(m12)[:-1]
</code>```

The last two lines are where I tried to implement the solution, but it didn't work.

Here is the method that puts the negative numbers in parentheses:

```<code>def format_num(num,justLen,justWithChar='.',howManyDecimal=0,putComma='Y',minusFormat='-',zeroChar='0'):
    if not num:
        num = 0

    if num == 0:
        if zeroChar <> '0':
            return zeroChar.rjust(justLen,justWithChar)

    roundedNum = round(num, howManyDecimal) # rounded becomes float
    if putComma=='Y': # put comma at thousand
        numStr = '{:,}'.format(roundedNum) # fractional part is truncated to 5 decimal place
    else:
        numStr = str(roundedNum)
    if howManyDecimal == 0:
        numStr = numStr.rsplit('.')[0] # 1,234.99 -> ['1,234', '99']
    else: # to pad with 0 ex) 4234.9 -> 4234.90
        numStr=numStr.rsplit('.')[0] + '.' + numStr.rsplit('.')[1].ljust(howManyDecimal, '0')

    if num < 0:
        if minusFormat=='P': # change - sign to parenthesis format
            numStr = numStr.replace('-', '(') + ')'

    return numStr.rjust(justLen,justWithChar)
</code>```

Here is the code from round_dolls():

```<code>def round_dolls(num, justLen, format='I', zeroChar='0'):
    if format == 'Q': # quantity - no comma - 99999
        return format_num(num, justLen, '.', 0, 'N','-',zeroChar)
    elif format == 'I': # integer - 99,999
        return format_num(num, justLen, '.', 0, 'Y','-',zeroChar)
    elif format == 'F': # float wit 2 decimal places - 99,999.99
        return format_num(num, justLen, '.', 2, 'Y','-',zeroChar)
    elif format == 'D': # 99,999 negative number (99,999)
        return format_num(num, justLen, '.', 0, 'Y','P',zeroChar)
    elif format == 'd': # 99,999.99 negative number (99,999.99)
        return format_num(num, justLen, '.', 2, 'Y','P',zeroChar)
    elif format == 'P': # percentage
        return format_num(num*100, justLen, '.', 0) + '%'
    else:
        return 'Format not specified'
</code>```

答:
Change:

```<code>if num < 0:
    if minusFormat=='P': # change - sign to parenthesis format
        numStr = numStr.replace('-', '(') + ')'
</code>```

to:

```<code>if minusFormat == 'P':
    if num < 0: # change - sign to parenthesis format
        numStr = numStr.replace('-', '(') + ')'
    else: # add extra character to positive values to line up with negative
        numStr = numStr + justWithChar
</code>```

If you don't want a . in the last character of the line, you can put this after the for c in range(len(line)) loop to remove the character if it's not ):

```<code>if rowStr[-1] != ')':
    rowStr = rowStr[:-1]
</code>```

Body:
Picture: Misaligned columns:

Please refer to the picture linked above. I have an email report showing negative values with parentheses around them. I need to make it do that the last digit in each number lines up with each other. The values are being printing by using for-loops and if-statements when running SQL statements. The values are printed as they run through the SQL statements.

How do I get the positive values to shift once to the left to align with the last digit of the numbers in parentheses?

Here are the for loops that print the columns in the report:

m1_total=0
m3_total=0
m6_total=0
m12_total=0

for line in curs:
    if (line[1]==0) or (line[1]==None): #skip if the M1 is 0
        continue

    m1=0
    m3=0
    m6=0
    m12=0
    if line[1]>0:
        m1=line[1]
    if line[2]>0:
        m3=round(line[2]/3)
    if line[3]>0:
        m6=round(line[3]/6)
    if line[4]>0:
        m12=round(line[4]/12)
    mc3=0
    mc6=0
    mc12=0
    if m3 > 0:
        mc3=round((m1/m3)*100-100,2)
    if m6>0:
        mc6=round((m3/m6)*100-100,2)
    if m12 > 0:
        mc12=round((m6/m12)*100-100,2)

    outStr+=str(line[0]).ljust(13,'.')+round_dolls(m1,9)+round_dolls(m3,9)+round_dolls(m6,9)+round_dolls(m12,9)
    outStr+=round_dolls(mc3,14,'d')+round_dolls(mc6,9,'d')+round_dolls(mc12,9,'d') + '
'
    m1_total+=m1
    m3_total+=m3
    m6_total+=m6
    m12_total+=m12
    mc3_total=0
    mc6_total=0
    mc12_total=0
    if m3_total > 0:
        mc3_total=round((m1_total/m3_total)*100-100,2)
    if m6_total>0:
        mc6_total=round((m3_total/m6_total)*100-100,2)
    if m12_total > 0:
        mc12_total=round((m6_total/m12_total)*100-100,2)

    if line[-1] != ')':
        str(m12) = str(m12)[:-1]

The last two lines are where I tried to implement the solution, but it didn't work.

Here is the method that puts the negative numbers in parentheses:

def format_num(num,justLen,justWithChar='.',howManyDecimal=0,putComma='Y',minusFormat='-',zeroChar='0'):
    if not num:
        num = 0

    if num == 0:
        if zeroChar <> '0':
            return zeroChar.rjust(justLen,justWithChar)

    roundedNum = round(num, howManyDecimal) # rounded becomes float
    if putComma=='Y': # put comma at thousand
        numStr = '{:,}'.format(roundedNum) # fractional part is truncated to 5 decimal place
    else:
        numStr = str(roundedNum)
    if howManyDecimal == 0:
        numStr = numStr.rsplit('.')[0] # 1,234.99 -> ['1,234', '99']
    else: # to pad with 0 ex) 4234.9 -> 4234.90
        numStr=numStr.rsplit('.')[0] + '.' + numStr.rsplit('.')[1].ljust(howManyDecimal, '0')

    if num < 0:
        if minusFormat=='P': # change - sign to parenthesis format
            numStr = numStr.replace('-', '(') + ')'

    return numStr.rjust(justLen,justWithChar)

Here is the code from round_dolls():

def round_dolls(num, justLen, format='I', zeroChar='0'):
    if format == 'Q': # quantity - no comma - 99999
        return format_num(num, justLen, '.', 0, 'N','-',zeroChar)
    elif format == 'I': # integer - 99,999
        return format_num(num, justLen, '.', 0, 'Y','-',zeroChar)
    elif format == 'F': # float wit 2 decimal places - 99,999.99
        return format_num(num, justLen, '.', 2, 'Y','-',zeroChar)
    elif format == 'D': # 99,999 negative number (99,999)
        return format_num(num, justLen, '.', 0, 'Y','P',zeroChar)
    elif format == 'd': # 99,999.99 negative number (99,999.99)
        return format_num(num, justLen, '.', 2, 'Y','P',zeroChar)
    elif format == 'P': # percentage
        return format_num(num*100, justLen, '.', 0) + '%'
    else:
        return 'Format not specified'

Body:
Change:

if num < 0:
    if minusFormat=='P': # change - sign to parenthesis format
        numStr = numStr.replace('-', '(') + ')'

to:

if minusFormat == 'P':
    if num < 0: # change - sign to parenthesis format
        numStr = numStr.replace('-', '(') + ')'
    else: # add extra character to positive values to line up with negative
        numStr = numStr + justWithChar

If you don't want a . in the last character of the line, you can put this after the for c in range(len(line)) loop to remove the character if it's not ):

if rowStr[-1] != ')':
    rowStr = rowStr[:-1]


问:
could not extract ResultSet; SQL [n/a]; nested exception is org.hibernate.exception.SQLGrammarException: could not extract ResultSet
I have that nativeQuery Query in my Repository.

```<code> @Query(value = "Select * from Company a  left join Industry b on a.industry_id=b.id", nativeQuery = true)
    public List < Company > findJoin();
</code>```

But when i run the Page I have that error

could not extract ResultSet; SQL [n/a]; nested exception is
org.hibernate.exception.SQLGrammarException: could not extract
ResultSet

```<code>Company

  @Entity
  public class Company {

    private long id;

    private String name;
    private String website;
    private String about;
    private String city;
    private int location;
    private int industry_id;

    /**
     * @return the industry_id
     */
    public int getIndustry_id() {
        return industry_id;
    }

    /**
     * @param industry_id the industry_id to set
     */
    public void setIndustry_id(int industry_id) {
        this.industry_id = industry_id;
    }

    private int numbere;

    private Industry industry;

    /**
     * @return the id
     */
    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    public long getId() {
        return id;
    }

    /**
     * @param id
     *            the id to set
     */
    public void setId(long id) {
        this.id = id;
    }

    /**
     * @return the name
     */
    public String getName() {
        return name;
    }

    /**
     * @param name
     *            the name to set
     */
    public void setName(String name) {
        this.name = name;
    }

    /**
     * @return the website
     */
    public String getWebsite() {
        return website;
    }

    /**
     * @param website
     *            the website to set
     */
    public void setWebsite(String website) {
        this.website = website;
    }

    /**
     * @return the about
     */
    public String getAbout() {
        return about;
    }

    /**
     * @param about
     *            the about to set
     */
    public void setAbout(String about) {
        this.about = about;
    }

    /**
     * @return the city
     */
    public String getCity() {
        return city;
    }

    /**
     * @param city
     *            the city to set
     */
    public void setCity(String city) {
        this.city = city;
    }

    /**
     * @return the location
     */
    public int getLocation() {
        return location;
    }

    /**
     * @param location
     *            the location to set
     */
    public void setLocation(int location) {
        this.location = location;
    }

    /**
     * @return the industry_id
     */

    /**
     * @param industry_id
     *            the industry_id to set
     */

    /**
     * @return the numbere
     */
    public int getNumbere() {
        return numbere;
    }

    /**
     * @param numbere
     *            the numbere to set
     */
    public void setNumbere(int numbere) {
        this.numbere = numbere;
    }

    /**
     * @return the industry
     */
    @ManyToOne
    @JoinColumn(name = "industry_id",insertable = false, updatable =
  false)
    public Industry getIndustry() {
        return industry;
    }

    /**
     * @param industry
     *            the industry to set
     */
    public void setIndustry(Industry industry) {
        this.industry = industry;
    }

    // private byte[] logo;

   }
</code>```

Industry

```<code> @Entity
public class Industry {

    @Column(name="ides")
    private long id;
    @Column(name="namens")
    private String name;

    private Set<Company> company;

    /**
     * @return the id
     */
    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    public long getId() {
        return id;
    }

    /**
     * @param id the id to set
     */
    public void setId(long id) {
        this.id = id;
    }

    /**
     * @return the name
     */
    public String getName() {
        return name;
    }

    /**
     * @param name the name to set
     */
    public void setName(String name) {
        this.name = name;
    }

    /**
     * @return the company
     */
    @OneToMany(mappedBy = "industry", cascade = CascadeType.ALL)
    public Set<Company> getCompany() {
        return company;
    }

    /**
     * @param company the company to set
     */

    public void setCompany(Set<Company> company) {
        this.company = company;
    }

}
</code>```

Can somehone hlp me please. Or how to convert this nativeQuery to Hibernate sql? Thanks

答:
Try this in your JPA repository

```<code>@Query("Select c from Company c where c.industry.id = :id")
List<Company> findJoin(@Param("id") long id);
</code>```

PS: Haven't tested this but it should work given that your mapping is correct.

Body:
I have that nativeQuery Query in my Repository.

 @Query(value = "Select * from Company a  left join Industry b on a.industry_id=b.id", nativeQuery = true)
    public List < Company > findJoin();

But when i run the Page I have that error

could not extract ResultSet; SQL [n/a]; nested exception is
org.hibernate.exception.SQLGrammarException: could not extract
ResultSet

Company

  @Entity
  public class Company {

    private long id;

    private String name;
    private String website;
    private String about;
    private String city;
    private int location;
    private int industry_id;

    /**
     * @return the industry_id
     */
    public int getIndustry_id() {
        return industry_id;
    }

    /**
     * @param industry_id the industry_id to set
     */
    public void setIndustry_id(int industry_id) {
        this.industry_id = industry_id;
    }

    private int numbere;

    private Industry industry;

    /**
     * @return the id
     */
    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    public long getId() {
        return id;
    }

    /**
     * @param id
     *            the id to set
     */
    public void setId(long id) {
        this.id = id;
    }

    /**
     * @return the name
     */
    public String getName() {
        return name;
    }

    /**
     * @param name
     *            the name to set
     */
    public void setName(String name) {
        this.name = name;
    }

    /**
     * @return the website
     */
    public String getWebsite() {
        return website;
    }

    /**
     * @param website
     *            the website to set
     */
    public void setWebsite(String website) {
        this.website = website;
    }

    /**
     * @return the about
     */
    public String getAbout() {
        return about;
    }

    /**
     * @param about
     *            the about to set
     */
    public void setAbout(String about) {
        this.about = about;
    }

    /**
     * @return the city
     */
    public String getCity() {
        return city;
    }

    /**
     * @param city
     *            the city to set
     */
    public void setCity(String city) {
        this.city = city;
    }

    /**
     * @return the location
     */
    public int getLocation() {
        return location;
    }

    /**
     * @param location
     *            the location to set
     */
    public void setLocation(int location) {
        this.location = location;
    }

    /**
     * @return the industry_id
     */

    /**
     * @param industry_id
     *            the industry_id to set
     */

    /**
     * @return the numbere
     */
    public int getNumbere() {
        return numbere;
    }

    /**
     * @param numbere
     *            the numbere to set
     */
    public void setNumbere(int numbere) {
        this.numbere = numbere;
    }

    /**
     * @return the industry
     */
    @ManyToOne
    @JoinColumn(name = "industry_id",insertable = false, updatable =
  false)
    public Industry getIndustry() {
        return industry;
    }

    /**
     * @param industry
     *            the industry to set
     */
    public void setIndustry(Industry industry) {
        this.industry = industry;
    }

    // private byte[] logo;

   }

Industry

 @Entity
public class Industry {

    @Column(name="ides")
    private long id;
    @Column(name="namens")
    private String name;

    private Set<Company> company;

    /**
     * @return the id
     */
    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    public long getId() {
        return id;
    }

    /**
     * @param id the id to set
     */
    public void setId(long id) {
        this.id = id;
    }

    /**
     * @return the name
     */
    public String getName() {
        return name;
    }

    /**
     * @param name the name to set
     */
    public void setName(String name) {
        this.name = name;
    }

    /**
     * @return the company
     */
    @OneToMany(mappedBy = "industry", cascade = CascadeType.ALL)
    public Set<Company> getCompany() {
        return company;
    }

    /**
     * @param company the company to set
     */

    public void setCompany(Set<Company> company) {
        this.company = company;
    }

}

Can somehone hlp me please. Or how to convert this nativeQuery to Hibernate sql? Thanks

Body:
Try this in your JPA repository

@Query("Select c from Company c where c.industry.id = :id")
List<Company> findJoin(@Param("id") long id);

PS: Haven't tested this but it should work given that your mapping is correct.


问:
Consecutive asynchronous test steps in ava

The problem

The popular ava package features a simple and powerful testing framework for javascript:

import test from 'ava';

test('single step', t => {
    t.is('bar', 'bar');
    t.end();
});
```

Testing is dead simple for synchronous code. However, I am not sure how to write tests with multiple, consecutive, dependent steps.

For example, I would like to test a REST API. I would like to create a resource using POST, make sure it exists with GET call, and delete it with DELETE.

Needless to say, the order matters: the POST call must be finished before the GET call can start, and sometimes we even want a sleep time between steps.

What have I tried

Tried a series of setTimeouts where where the callback of each call is the next test step. It is fairly unreadable.

My question

What's the right way to write a test with multiple consecutive steps with ava?

These steps are asynchronous and consecutive

答:
You can mix slow functions and logic into complex scenarios if you run your code via sequential executor nsynjs. You just need to write your code as if it was synchronous, and put it into function:

```<code>function process() {
    var data = jQueryGetJSON(nsynjsCtx, "data/index.json").data; // ajax call to get some data
    for(var i in data) { // data is ready at this point
        var resp = jQueryGetJSON(nsynjsCtx, "data/"+data[i]).data;  // another ajax call
        // ... resp is ready here, do processing of resp...
        nsynWait(nsynjsCtx,100); // wait 100ms
    }
    return someResult;
}
</code>```

Then you run that function via nsynjs:

```<code>nsynjs.run(process,this,function (someResult) {
    console.log('done');
    // put t.end() inside this callback
});
</code>```

See more examples here: https://github.com/amaksr/nsynjs/tree/master/examples

Body:
The problem

The popular ava package features a simple and powerful testing framework for javascript:

import test from 'ava';

test('single step', t => {
    t.is('bar', 'bar');
    t.end();
});

Testing is dead simple for synchronous code. However, I am not sure how to write tests with multiple, consecutive, dependent steps.

For example, I would like to test a REST API. I would like to create a resource using POST, make sure it exists with GET call, and delete it with DELETE.

Needless to say, the order matters: the POST call must be finished before the GET call can start, and sometimes we even want a sleep time between steps.

What have I tried

Tried a series of setTimeouts where where the callback of each call is the next test step. It is fairly unreadable.

My question

What's the right way to write a test with multiple consecutive steps with ava?

These steps are asynchronous and consecutive

Body:
You can mix slow functions and logic into complex scenarios if you run your code via sequential executor nsynjs. You just need to write your code as if it was synchronous, and put it into function:

function process() {
    var data = jQueryGetJSON(nsynjsCtx, "data/index.json").data; // ajax call to get some data
    for(var i in data) { // data is ready at this point
        var resp = jQueryGetJSON(nsynjsCtx, "data/"+data[i]).data;  // another ajax call
        // ... resp is ready here, do processing of resp...
        nsynWait(nsynjsCtx,100); // wait 100ms
    }
    return someResult;
}

Then you run that function via nsynjs:

nsynjs.run(process,this,function (someResult) {
    console.log('done');
    // put t.end() inside this callback
});

See more examples here: https://github.com/amaksr/nsynjs/tree/master/examples


问:
How to retrieve high quality compass orientation (as in Google Maps)?
All of the guides to getting compass orientation in Android I've found have a bug: when you hold the phone in portrait mode and "look" above the horizon, the compass arrow turns 180 degrees from the correct direction.

Google Maps orientation indicator doesn't have this problem.

Another nice thing that Google Maps have is that they somehow estimate compass accuracy. Any idea how they do this?

答:
Error you ask is caused because of Euler angles or called Gimbal Lock.

To solve very high angle difference, you should check if your device is flat or not checking inclination after getting inclination using gravity sensor or getting gravity from accelerometer with lowpass filter. If it's not flat(AR application or inclination>25 || inclination < 155) remap coordinate system from x,y to x,z. That will solve the issue.

```<code>SensorManager.getRotationMatrixFromVector(rotationMatrix, event.values);
SensorManager.remapCoordinateSystem(rotationMatrix, SensorManager.AXIS_X, SensorManager.AXIS_Z, remappedRM);
SensorManager.getOrientation(remappedRM, orientation);
</code>```

This solves the Gimbal Lock, however, 3D compasses(normal compasses does not give correct results due to they are only mapped in x,y and occurs Gimbal Lock) i've seen on Play Store and every code here has a diffence when you keep your device laying flat or screen pointing at you. That difference sometimes gets up to 10 degrees. I haven't able to solve it. Mostly difference is between 1-5 degrees but i sometimes see it rise up to 10 degrees which is not acceptable.

Google measures azimuth from your location. There is a code to find bearing.

```<code>currentLocation.getBearing();
</code>```

Accuracy of lat long(accuracy of your current location) is what determines accuracy of bearing.

List of ways doing a compass with the most accurate to least is in order

Use GPS/Wife(Google's fused location) location and get bearing from location

Use Rotation Vector(requires magnetic field sensor, you should check if it's available), it's a fused sensor(magnetic field+gyroscope+accelerometer and software parts) and using Kalman filter to smooth values but check inclination to remap orientation

Gravity/Accelerometer + Magnetic Field Sensor. This will have a terrible noise attached to it, to smooth it you should use moving average or low-pass filter(this not for isolating gravity, it's for using a threshold frequency to prevent high jumps)

Body:
Error you ask is caused because of Euler angles or called Gimbal Lock.

To solve very high angle difference, you should check if your device is flat or not checking inclination after getting inclination using gravity sensor or getting gravity from accelerometer with lowpass filter. If it's not flat(AR application or inclination>25 || inclination < 155) remap coordinate system from x,y to x,z. That will solve the issue.

SensorManager.getRotationMatrixFromVector(rotationMatrix, event.values);
SensorManager.remapCoordinateSystem(rotationMatrix, SensorManager.AXIS_X, SensorManager.AXIS_Z, remappedRM);
SensorManager.getOrientation(remappedRM, orientation);

This solves the Gimbal Lock, however, 3D compasses(normal compasses does not give correct results due to they are only mapped in x,y and occurs Gimbal Lock) i've seen on Play Store and every code here has a diffence when you keep your device laying flat or screen pointing at you. That difference sometimes gets up to 10 degrees. I haven't able to solve it. Mostly difference is between 1-5 degrees but i sometimes see it rise up to 10 degrees which is not acceptable.

Google measures azimuth from your location. There is a code to find bearing.

currentLocation.getBearing();

Accuracy of lat long(accuracy of your current location) is what determines accuracy of bearing.

List of ways doing a compass with the most accurate to least is in order

Use GPS/Wife(Google's fused location) location and get bearing from location

Use Rotation Vector(requires magnetic field sensor, you should check if it's available), it's a fused sensor(magnetic field+gyroscope+accelerometer and software parts) and using Kalman filter to smooth values but check inclination to remap orientation

Gravity/Accelerometer + Magnetic Field Sensor. This will have a terrible noise attached to it, to smooth it you should use moving average or low-pass filter(this not for isolating gravity, it's for using a threshold frequency to prevent high jumps)


问:
Crystal Report 11 hangs on Launch
I launch the crystal Report software but it hangs with a busy cursor and does not return back to normal state. But if I turn of my internet connection and re launch, then it works just fine. What is the issue?</p>

答:
I had the same thing happen today.  My guess is there is an issue with the update server.  Get Crystal to Launch by disabling your network, and then under Help, uncheck the Check for Updates on Startup.

Everything started working for me as normal after that even with my network turned on.

Title: Crystal Report 11 hangs on Launch


问:
Monitor Outbound Webservice calls
I'm currently debugging a 3rd party component and I need to monitor to see if it is making an outbound webservice call. Does anyone know of a way of quickly setting up something to monitor this as I step over the code. </p>

答:
I would get wireshark. It can trace network packets, its a quick install.

http://www.wireshark.org/

ContentLicense: CC BY-SA 2.5

Title: Monitor Outbound Webservice calls


问:
Starting different activities from MainActivity
I'm new here and I think I have made a mistake in Java but I have no idea how to correct it. Most of the people with similar issue had much more complicated projects and I couldn't resolve my issue by looking at their code.

I want to use different buttons (9 of them) to start different activities, but when I started with adding the second, only the activity 1 (LeftArmActivity) popped up. Whatever I changed in the XML to call the proper method for HeadActivity to launch, only the LeftActivity launches. I've got a hint from other topics that it may be caused by overwriting of the intent, but I have no idea how to fix this. I tried to use getActivity() but it just crashed. Could you please help me with this?

@UPDATE

Okay, I used the switch recommended below, but now the app won't start at all :/

```<code> public class MainActivity extends AppCompatActivity {

Context context = this;
Button LeftArmOpener = (Button) findViewById(R.id.LeftArmOpener);
Button HeadOpener = (Button) findViewById(R.id.HeadOpener);
Button RightArmOpener = (Button) findViewById(R.id.RightArmOpener);
Button CreditsOpener = (Button) findViewById(R.id.CreditsOpener);
Button TrunkOpener = (Button) findViewById(R.id.TrunkOpener);
Button NextOpener = (Button) findViewById(R.id.NextOpener);
Button RightLegOpener = (Button) findViewById(R.id.RightLegOpener);
Button ExitOpener = (Button) findViewById(R.id.ExitOpener);
Button LeftLegOpener = (Button) findViewById(R.id.LeftLegOpener);

protected View.OnClickListener mClick;

protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);

    mClick = new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            switch (v.getId()) {
                case R.id.RightArmOpener: {
                    Intent i1 = new Intent(context, LeftArmActivity.class);
                    startActivity(i1);
                    break;
                }
                case R.id.HeadOpener: {
                    Intent i2 = new Intent(context, HeadActivity.class);
                    startActivity(i2);
                    break;
                }
                case R.id.LeftArmOpener: {
                    Intent i3 = new Intent(context, LeftArmActivity.class);
                    startActivity(i3);
                    break;
                }
                case R.id.CreditsOpener: {
                    Intent i4 = new Intent(context, CreditsActivity.class);
                    startActivity(i4);
                    break;
                }
                case R.id.TrunkOpener: {
                    Intent i5 = new Intent(context, TrunkActivity.class);
                    startActivity(i5);
                    break;
                }
                case R.id.NextOpener: {
                    Intent i6 = new Intent(context, NextActivity.class);
                    startActivity(i6);
                    break;
                }
                case R.id.RightLegOpener: {
                    Intent i7 = new Intent(context, RightLegActivity.class);
                    startActivity(i7);
                    break;
                }
                case R.id.ExitOpener: {
                    Intent i8 = new Intent(context, ExitActivity.class);
                    startActivity(i8);
                    break;
                }
                case R.id.LeftLegOpener: {
                    Intent i9 = new Intent(context, LeftLegActivity.class);
                    startActivity(i9);
                    break;
                }
                //create this for all 9 buttons
            }

        }

    };

    LeftArmOpener.setOnClickListener(mClick);
    HeadOpener.setOnClickListener(mClick);
    RightArmOpener.setOnClickListener(mClick);
    CreditsOpener.setOnClickListener(mClick);
    TrunkOpener.setOnClickListener(mClick);
    NextOpener.setOnClickListener(mClick);
    RightLegOpener.setOnClickListener(mClick);
    ExitOpener.setOnClickListener(mClick);
    LeftLegOpener.setOnClickListener(mClick);

}
</code>```

}

答:
On the top declare your button; (before the oncreate method)

```<code> Button yourbuttonname;
</code>```

Then on the oncreate method:

declare the view of the button:

```<code>yourbuttonname = (Button) findViewById(R.id.buttonNameInYourXML);
 yourbuttonname.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
       Intent intent = new Intent(ActualActivity.this, ActivityYouWantToGo.class);
                intent.putExtra("tag",valueassociatedtotag); // if you want to pass some data
                startActivity(intent)
            }
        });
</code>```

Body:
I'm new here and I think I have made a mistake in Java but I have no idea how to correct it. Most of the people with similar issue had much more complicated projects and I couldn't resolve my issue by looking at their code.

I want to use different buttons (9 of them) to start different activities, but when I started with adding the second, only the activity 1 (LeftArmActivity) popped up. Whatever I changed in the XML to call the proper method for HeadActivity to launch, only the LeftActivity launches. I've got a hint from other topics that it may be caused by overwriting of the intent, but I have no idea how to fix this. I tried to use getActivity() but it just crashed. Could you please help me with this?

@UPDATE

Okay, I used the switch recommended below, but now the app won't start at all :/

 public class MainActivity extends AppCompatActivity {

Context context = this;
Button LeftArmOpener = (Button) findViewById(R.id.LeftArmOpener);
Button HeadOpener = (Button) findViewById(R.id.HeadOpener);
Button RightArmOpener = (Button) findViewById(R.id.RightArmOpener);
Button CreditsOpener = (Button) findViewById(R.id.CreditsOpener);
Button TrunkOpener = (Button) findViewById(R.id.TrunkOpener);
Button NextOpener = (Button) findViewById(R.id.NextOpener);
Button RightLegOpener = (Button) findViewById(R.id.RightLegOpener);
Button ExitOpener = (Button) findViewById(R.id.ExitOpener);
Button LeftLegOpener = (Button) findViewById(R.id.LeftLegOpener);

protected View.OnClickListener mClick;

protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);

    mClick = new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            switch (v.getId()) {
                case R.id.RightArmOpener: {
                    Intent i1 = new Intent(context, LeftArmActivity.class);
                    startActivity(i1);
                    break;
                }
                case R.id.HeadOpener: {
                    Intent i2 = new Intent(context, HeadActivity.class);
                    startActivity(i2);
                    break;
                }
                case R.id.LeftArmOpener: {
                    Intent i3 = new Intent(context, LeftArmActivity.class);
                    startActivity(i3);
                    break;
                }
                case R.id.CreditsOpener: {
                    Intent i4 = new Intent(context, CreditsActivity.class);
                    startActivity(i4);
                    break;
                }
                case R.id.TrunkOpener: {
                    Intent i5 = new Intent(context, TrunkActivity.class);
                    startActivity(i5);
                    break;
                }
                case R.id.NextOpener: {
                    Intent i6 = new Intent(context, NextActivity.class);
                    startActivity(i6);
                    break;
                }
                case R.id.RightLegOpener: {
                    Intent i7 = new Intent(context, RightLegActivity.class);
                    startActivity(i7);
                    break;
                }
                case R.id.ExitOpener: {
                    Intent i8 = new Intent(context, ExitActivity.class);
                    startActivity(i8);
                    break;
                }
                case R.id.LeftLegOpener: {
                    Intent i9 = new Intent(context, LeftLegActivity.class);
                    startActivity(i9);
                    break;
                }
                //create this for all 9 buttons
            }

        }

    };

    LeftArmOpener.setOnClickListener(mClick);
    HeadOpener.setOnClickListener(mClick);
    RightArmOpener.setOnClickListener(mClick);
    CreditsOpener.setOnClickListener(mClick);
    TrunkOpener.setOnClickListener(mClick);
    NextOpener.setOnClickListener(mClick);
    RightLegOpener.setOnClickListener(mClick);
    ExitOpener.setOnClickListener(mClick);
    LeftLegOpener.setOnClickListener(mClick);

}

}

Body:
On the top declare your button; (before the oncreate method)

 Button yourbuttonname;

Then on the oncreate method:

declare the view of the button:

yourbuttonname = (Button) findViewById(R.id.buttonNameInYourXML);
 yourbuttonname.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
       Intent intent = new Intent(ActualActivity.this, ActivityYouWantToGo.class);
                intent.putExtra("tag",valueassociatedtotag); // if you want to pass some data
                startActivity(intent)
            }
        });


问:
Mosquitto publish message format to android app
I am working on a IoT project where i'm using mosquitto broker to get messages to my android app. But when i receive the published messages on my app, they appear to be in a weird format. how can i get the data in correct format. Do i need to change something in mosquitto configuration.

The data sent: "hello"

Received on app: [B@2df51a89

this is what i use to get the text in onMessageReceived(topic,message)
message.getPayload().toString();

Any help is appreciated.

[UPDATE] - When i publish data FROM mobile app, the data is received perfectly at the subscriber. Vice versa doesn't work.

答:
You've printed out the object representation of the byte array (message payload). The correct thing to have done is to create a new String from the byte array using a known encoding (probably UTF8)

```<code>String payload = new String(message.getPayload(), "utf8")
</code>```

Then print the payload String

Body:
You've printed out the object representation of the byte array (message payload). The correct thing to have done is to create a new String from the byte array using a known encoding (probably UTF8)

String payload = new String(message.getPayload(), "utf8")

Then print the payload String


问:
boolean example in Schildt book
I'm really new to Java, but it sucks all my free time, it's very interesting to study, but I need a little help.

Here's an example of Boolean test from Schildt's book:

```<code>public class BooleanTest {
public static void main(String args[]){
    boolean b;
    b = false;
    System.out.println("Expression b " +b);
    b = true;
    System.out.println("Expression b " + b);
    if (b) System.out.println("This code is ok.");
    b = false;
    if (b) System.out.println("This code is not ok.");
    System.out.println("10 > 9 " + (10>9));
}}
</code>```

This code shows me result:

Expression b false

Expression b true

This code is ok.

10 > 9 true

First line is ok, second is ok, third too, but why the fourth doesn't show me "The code is not ok.", 'cause there is "b=false" and it should say that? Why it jumps to the last System.out.println?

Can someone add commentaries to this example? Thanks a lot!

答:
if (b) equal to if(b!=false)

and as you see the third placement is  b=true

fourth placement is b=false but the condition is the same if (b) = if(b!=false).

Title: boolean example in Schildt book

Body:
I'm really new to Java, but it sucks all my free time, it's very interesting to study, but I need a little help.

Here's an example of Boolean test from Schildt's book:

public class BooleanTest {
public static void main(String args[]){
    boolean b;
    b = false;
    System.out.println("Expression b " +b);
    b = true;
    System.out.println("Expression b " + b);
    if (b) System.out.println("This code is ok.");
    b = false;
    if (b) System.out.println("This code is not ok.");
    System.out.println("10 > 9 " + (10>9));
}}

This code shows me result:

Expression b false

Expression b true

This code is ok.

10 > 9 true

First line is ok, second is ok, third too, but why the fourth doesn't show me "The code is not ok.", 'cause there is "b=false" and it should say that? Why it jumps to the last System.out.println?

Can someone add commentaries to this example? Thanks a lot!


问:
How to get the list of application names and uninstall strings from JSON file and pass them as parameters to uninstall an application using powershell
I would like to read JSON file to get the list of application names and their respective uninstall strings and pass them as arguments in power shell to uninstall the apps irrespective of whether the apps are Windows Installer(MSI) or setup. Can someone please suggest me how to do this. Thanks</p>

答:
Thank you for suggesting the answer, that worked. I used the following cmd-line

$J = Get-Content -Raw -Path $scriptDirectory\Files\XXX.json | ConvertFrom-Json
and passed the AppName property as given below to fetch the application names:
 $AppName = $J |fl -Property AppName.

FYI.. my JSON file content looked as follows:

[
     {
       "AppName": "xxxxx",
       "AppVersion": "aa.bb"
     },

```<code> {
   "AppName": "yyy",
   "AppVersion": "aa.bb.cc"
 }
</code>```

]

Body:
Thank you for suggesting the answer, that worked. I used the following cmd-line

$J = Get-Content -Raw -Path $scriptDirectory\Files\XXX.json | ConvertFrom-Json
and passed the AppName property as given below to fetch the application names:
 $AppName = $J |fl -Property AppName.

FYI.. my JSON file content looked as follows:

[
     {
       "AppName": "xxxxx",
       "AppVersion": "aa.bb"
     },

 {
   "AppName": "yyy",
   "AppVersion": "aa.bb.cc"
 }

]


答:
Here is a simple routine which should give you the concrete knowledge

```<code>if (true) {
   //do true
}

if (false) {
   // not true, never go here
}
</code>```

Using curly brackets to ensure multiple lines get included in the block else only 1 line directly after the "if" is executed.

Title: boolean example in Schildt book

Body:
Here is a simple routine which should give you the concrete knowledge

if (true) {
   //do true
}

if (false) {
   // not true, never go here
}

Using curly brackets to ensure multiple lines get included in the block else only 1 line directly after the "if" is executed.


问:
Can `typeof(T).IsAssignableFrom(x.GetType())` be safely rewritten as `x is T`?

Note: This is not a duplicate of "Use of IsAssignableFrom and “is” keyword in C#". That other question asks about typeof(T).IsAssignableFrom(type)), where type is not an object but a Type.

This seems trivial — I can hear you saying, "Just call x.GetType()!" — but due to the COM-related corner case mentioned below, that call causes problems, which is why I'm asking about the rewrite.

… or are there rare special cases where the two might give different results?

I stumbled upon a type check of the form:

```<code>typeof(TValue).IsAssignableFrom(value.GetType())
</code>```

where TValue is a generic type parameter (without any constraints) and value is an object.

I am not entirely sure whether it is safe to rewrite the above simply as:

```<code>value is TValue
</code>```

To my current knowledge, the two tests are equivalent with the exception of COM objects. is should trigger a proper QueryInterface, while IsAssignableFrom might get confused by the __ComObject RCW wrapper type and report a false negative.

Are there any other differences between is and the shown use of IsAssignableFrom?

答:
There are more cases where is and IsAssignableFrom returns different results, not just the one you mentioned for COM objects. For pair of array types with elements of type ElementType1 and ElementType2, where underlaying types of both element types are integer types of the same size but with opposite signedness, then

typeof(ElementType1[]).IsAssignableFrom(typeof(ElementType2[])) returns true but

new ElementType2[0] is ElementType1[] returns false

Specifically this includes arrays with these pairs of their element types:

byte / sbyte, short / ushort, int / uint, long / ulong

IntPtr / UIntPtr

any combination of enum type and either integer type or another enum type as long as underlaying types are of the same size

any combination of IntPtr / UIntPtr / int / uint in 32-bit process

any combination of IntPtr / UIntPtr / long / ulong in 64-bit process

This is due to differences in type system of C# and CLR as explained in

Why does my C# array lose type sign information when cast to object?

Why does “int[] is uint[] == true” in C#

Why is covariance of value-typed arrays inconsistent?

Different results of is and IsAssignableFrom in all cases mentioned above results from the fact that for new ElementType2[0] is ElementType1[] C# compiler simply emits False at compile-time (because it sees no way that for example int[] can be cast to uint[] as these are completly different types from C# perspective), completly omitting any runtime type checks. Fortunately casting array to object ((object)new ElementType2[0]) is ElementType1[] forces compiler to emit isinst IL instruction, which performs runtime type-check, that returns results consistent with IsAssignableFrom. This is also true for cases where target type is generic parameter, because it's type is not known at compile-time and C# compiler must emit isinst. So if you intend to replace IsAssignableFrom by is only in places where target type is generic parameter (as suggested in question title), I believe that these differences does not metter for you.

Body:
Note: This is not a duplicate of "Use of IsAssignableFrom and “is” keyword in C#". That other question asks about typeof(T).IsAssignableFrom(type)), where type is not an object but a Type.

This seems trivial — I can hear you saying, "Just call x.GetType()!" — but due to the COM-related corner case mentioned below, that call causes problems, which is why I'm asking about the rewrite.

… or are there rare special cases where the two might give different results?

I stumbled upon a type check of the form:

typeof(TValue).IsAssignableFrom(value.GetType())

where TValue is a generic type parameter (without any constraints) and value is an object.

I am not entirely sure whether it is safe to rewrite the above simply as:

value is TValue

To my current knowledge, the two tests are equivalent with the exception of COM objects. is should trigger a proper QueryInterface, while IsAssignableFrom might get confused by the __ComObject RCW wrapper type and report a false negative.

Are there any other differences between is and the shown use of IsAssignableFrom?


问:
How to get data from JSON and convert into the object?
I'm trying to receive data from request response which is JSON like this:

{
  "cnt":1,
  "list":[{
      "coord":{
          "lon":18.55,
          "lat":50.11
      },
      "sys":{
          "type":1,
          "id":5356,
          "message":0.0095,
          "country":"PL",
          "sunrise":1496630290,
          "sunset":1496688673
      },
      "weather":[{
          "id":800,
          "main":"Clear",
          "description":"clear sky",
          "icon":"01d"
      }],
      "main":{
          "temp":293.71,
          "pressure":1014,
          "humidity":42,
          "temp_min":293.15,
          "temp_max":294.15
      },
      "visibility":10000,
      "wind":{
          "speed":4.1,
          "deg":60
      },
      "clouds":{
          "all":0
      },
      "dt":1496686603,
      "id":7531758,
      "name":"Rybnik"
  }]
  }

I'm trying to use JSON.NET to deserialize JSON and receive data. But I don't know exactly how to do it properly.
I tried to achieve this by using my class method:

```<code>    public Rootobject DeserializeJSON()
    {
        private JObject responseObject;

        private JToken responseToken;

        private JArray responseArray;

        responseObject = JObject.Parse(json);

        Rootobject Weather = new Rootobject();

        responseArray = (JArray)responseObject.SelectToken("list");

        responseToken = (JToken)responseArray.SelectToken("main");

        Weather = responseToken.ToObject<Rootobject>();

        return Weather;
    }
</code>```

But It doesn't seems to work. In this case, I tried to receive data from "main" property in JSON and convert in to my class object:

```<code>class Main
{
    public float temp { get; set; }

    public float pressure { get; set; }

    public float humidity { get; set; }

    public float temp_min { get; set; }

    public float temp_max { get; set; }
}
</code>```

Could you explain me, how it should works and where's my fault, please?

答:
Initially, you need to declare the following classes:

```<code>public class Coord
{
    [JsonProperty("lon")]
    public double Lon { get; set; }

    [JsonProperty("lat")]
    public double Lat { get; set; }
}

public class Sys
{
    [JsonProperty("type")]
    public int Type { get; set; }

    [JsonProperty("id")]
    public int Id { get; set; }

    [JsonProperty("message")]
    public double Message { get; set; }

    [JsonProperty("country")]
    public string Country { get; set; }

    [JsonProperty("sunrise")]
    public int Sunrise { get; set; }

    [JsonProperty("sunset")]
    public int Sunset { get; set; }
}

public class Weather
{
    [JsonProperty("id")]
    public int Id { get; set; }

    [JsonProperty("main")]
    public string Main { get; set; }

    [JsonProperty("description")]
    public string Description { get; set; }

    [JsonProperty("icon")]
    public string Icon { get; set; }
}

public class Main
{
    [JsonProperty("temp")]
    public double Temp { get; set; }

    [JsonProperty("pressure")]
    public int Pressure { get; set; }

    [JsonProperty("humidity")]
    public int Humidity { get; set; }

    [JsonProperty("temp_min")]
    public double TempMin { get; set; }

    [JsonProperty("temp_max")]
    public double TempMax { get; set; }
}

public class Wind
{

    [JsonProperty("speed")]
    public double Speed { get; set; }

    [JsonProperty("deg")]
    public int Deg { get; set; }
}

public class Clouds
{

    [JsonProperty("all")]
    public int All { get; set; }
}

public class List
{
    [JsonProperty("coord")]
    public Coord Coord { get; set; }

    [JsonProperty("sys")]
    public Sys Sys { get; set; }

    [JsonProperty("weather")]
    public IList<Weather> Weather { get; set; }

    [JsonProperty("main")]
    public Main Main { get; set; }

    [JsonProperty("visibility")]
    public int Visibility { get; set; }

    [JsonProperty("wind")]
    public Wind Wind { get; set; }

    [JsonProperty("clouds")]
    public Clouds Clouds { get; set; }

    [JsonProperty("dt")]
    public int Dt { get; set; }

    [JsonProperty("id")]
    public int Id { get; set; }

    [JsonProperty("name")]
    public string Name { get; set; }
}

public class Example
{

    [JsonProperty("cnt")]
    public int Cnt { get; set; }

    [JsonProperty("list")]
    public IList<List> List { get; set; }
}
</code>```

Then you can deserialize your json as below:

```<code>var example = JsonConvert.DeserializeObject<Example>(jsonString)
</code>```

where jsonString is your JSON.

PS. I derived the above classes using jsonutils and your json string.

Body:
I'm trying to receive data from request response which is JSON like this:

{
  "cnt":1,
  "list":[{
      "coord":{
          "lon":18.55,
          "lat":50.11
      },
      "sys":{
          "type":1,
          "id":5356,
          "message":0.0095,
          "country":"PL",
          "sunrise":1496630290,
          "sunset":1496688673
      },
      "weather":[{
          "id":800,
          "main":"Clear",
          "description":"clear sky",
          "icon":"01d"
      }],
      "main":{
          "temp":293.71,
          "pressure":1014,
          "humidity":42,
          "temp_min":293.15,
          "temp_max":294.15
      },
      "visibility":10000,
      "wind":{
          "speed":4.1,
          "deg":60
      },
      "clouds":{
          "all":0
      },
      "dt":1496686603,
      "id":7531758,
      "name":"Rybnik"
  }]
  }

I'm trying to use JSON.NET to deserialize JSON and receive data. But I don't know exactly how to do it properly.
I tried to achieve this by using my class method:

    public Rootobject DeserializeJSON()
    {
        private JObject responseObject;

        private JToken responseToken;

        private JArray responseArray;

        responseObject = JObject.Parse(json);

        Rootobject Weather = new Rootobject();

        responseArray = (JArray)responseObject.SelectToken("list");

        responseToken = (JToken)responseArray.SelectToken("main");

        Weather = responseToken.ToObject<Rootobject>();

        return Weather;
    }

But It doesn't seems to work. In this case, I tried to receive data from "main" property in JSON and convert in to my class object:

class Main
{
    public float temp { get; set; }

    public float pressure { get; set; }

    public float humidity { get; set; }

    public float temp_min { get; set; }

    public float temp_max { get; set; }
}

Could you explain me, how it should works and where's my fault, please?

Body:
Initially, you need to declare the following classes:

public class Coord
{
    [JsonProperty("lon")]
    public double Lon { get; set; }

    [JsonProperty("lat")]
    public double Lat { get; set; }
}

public class Sys
{
    [JsonProperty("type")]
    public int Type { get; set; }

    [JsonProperty("id")]
    public int Id { get; set; }

    [JsonProperty("message")]
    public double Message { get; set; }

    [JsonProperty("country")]
    public string Country { get; set; }

    [JsonProperty("sunrise")]
    public int Sunrise { get; set; }

    [JsonProperty("sunset")]
    public int Sunset { get; set; }
}

public class Weather
{
    [JsonProperty("id")]
    public int Id { get; set; }

    [JsonProperty("main")]
    public string Main { get; set; }

    [JsonProperty("description")]
    public string Description { get; set; }

    [JsonProperty("icon")]
    public string Icon { get; set; }
}

public class Main
{
    [JsonProperty("temp")]
    public double Temp { get; set; }

    [JsonProperty("pressure")]
    public int Pressure { get; set; }

    [JsonProperty("humidity")]
    public int Humidity { get; set; }

    [JsonProperty("temp_min")]
    public double TempMin { get; set; }

    [JsonProperty("temp_max")]
    public double TempMax { get; set; }
}

public class Wind
{

    [JsonProperty("speed")]
    public double Speed { get; set; }

    [JsonProperty("deg")]
    public int Deg { get; set; }
}

public class Clouds
{

    [JsonProperty("all")]
    public int All { get; set; }
}

public class List
{
    [JsonProperty("coord")]
    public Coord Coord { get; set; }

    [JsonProperty("sys")]
    public Sys Sys { get; set; }

    [JsonProperty("weather")]
    public IList<Weather> Weather { get; set; }

    [JsonProperty("main")]
    public Main Main { get; set; }

    [JsonProperty("visibility")]
    public int Visibility { get; set; }

    [JsonProperty("wind")]
    public Wind Wind { get; set; }

    [JsonProperty("clouds")]
    public Clouds Clouds { get; set; }

    [JsonProperty("dt")]
    public int Dt { get; set; }

    [JsonProperty("id")]
    public int Id { get; set; }

    [JsonProperty("name")]
    public string Name { get; set; }
}

public class Example
{

    [JsonProperty("cnt")]
    public int Cnt { get; set; }

    [JsonProperty("list")]
    public IList<List> List { get; set; }
}

Then you can deserialize your json as below:

var example = JsonConvert.DeserializeObject<Example>(jsonString)

where jsonString is your JSON.

PS. I derived the above classes using jsonutils and your json string.


问:
What is Angular2 way of creating global keyboard shortcuts (a.k.a. hotkeys)?
What would be proper way of creating global keyboard shortcuts (a.k.a. hotkeys) in Angular2 application?

Let's say good starting point would be to get working: "?" for cheat-sheet and "Alt+s" for submitting form.

Should I map "?" somehow to main component and then develop attribute directive that would be applied to those components which should respond on particular hotkeys, but then - how do I prevent input fields from responding to "?".

答:
A simple and elegant solution will look like as following:-

Create a global service, which will store the bindings of shortcuts with clickable elements.
Note:- Use NgOnDestroy, for removing bindings on component is destroyed.

Now create a directive, which will take keycodes as input like this.

```<code><button [angularHotKey]="[17,78]">New Document</button>
<!-- CTRL = 17 & n = 78 -->
</code>```

Now in your root most component, listen keypresses and use them as indices for locating Elements in Global Service for HotKeys. Now on getting the reference do something like this.

I assume you have formatted recorded keycodes in this format =
  1-23-32-... , dont forget to sort them in ascending/descending format,
  both while adding it to keypair array in service and while checking

```<code>if(this.keypair[combo].length)this.keypair[combo].click();
</code>```

this.keypair[combo] contain reference of element on which angularHotKey directive was added.

Further Notes:
1.) In angularHotKey directive while adding new keypair and element/clickable reference please check if there don't exist pairing with same combo, if yes throw a exception, it will be helpful while debugging, and prevent you from doing silly mistakes, and in Angular 2 component class,in ngOnDestroy method define a logic of removing all shortcuts paired with it's child elements.

Visit http://keycode.info/ for getting keycodes for all types of keys present on your keyboard.

JavaScript multiple keys pressed at once  A answer with every little detail about how to deal with combo key presses

Body:
A simple and elegant solution will look like as following:-

Create a global service, which will store the bindings of shortcuts with clickable elements.
Note:- Use NgOnDestroy, for removing bindings on component is destroyed.

Now create a directive, which will take keycodes as input like this.

<button [angularHotKey]="[17,78]">New Document</button>
<!-- CTRL = 17 & n = 78 -->

Now in your root most component, listen keypresses and use them as indices for locating Elements in Global Service for HotKeys. Now on getting the reference do something like this.

I assume you have formatted recorded keycodes in this format =
  1-23-32-... , dont forget to sort them in ascending/descending format,
  both while adding it to keypair array in service and while checking

if(this.keypair[combo].length)this.keypair[combo].click();

this.keypair[combo] contain reference of element on which angularHotKey directive was added.

Further Notes:
1.) In angularHotKey directive while adding new keypair and element/clickable reference please check if there don't exist pairing with same combo, if yes throw a exception, it will be helpful while debugging, and prevent you from doing silly mistakes, and in Angular 2 component class,in ngOnDestroy method define a logic of removing all shortcuts paired with it's child elements.

Visit http://keycode.info/ for getting keycodes for all types of keys present on your keyboard.

JavaScript multiple keys pressed at once  A answer with every little detail about how to deal with combo key presses


问:
Debugging source files using chrome extension
I am trying to control the debugger using Chrome Extension.

I am using devtools-protocol and chrome extension documentation, but I have no idea how to implement them as I have not seen any samples of the methods in use. I used the sample extension from here which shows how to pause and resume the debugger only, but that's absolutely no use to me. I tried to implement some methods in the sample, but nothing happens.

```<code>function onDebuggerEnabled(debuggeeId) {
  chrome.debugger.sendCommand(debuggeeId, "Debugger.setBreakpointByUrl", {
        lineNumber: 45825,
        url: 'full https link to the js file from source tab'
  });
}
</code>```

The problem is that the js file I am trying to debug is loaded from the website inside the sources tab and it's huge, we talking 150k+ lines after its been formatted and it takes some time to load.

Now can anyone tell me how to simply add a break point inside the js file from the sources (USING CHROME EXTENSION) so it could be triggered on action which will then stops the debugger so I could change values etc?

答:
Maybe you are placing wrong breakpoint location (formatted source), try working with original source and add columnNumber: integer

and here working version JavaScript pause/resume -> background.js:

install this extension

open https://ewwink.github.io/demo/Debugger.setBreakpointByUrl.html

click debugger pause button

click button "Debug Me!"

it will hit breakpoint on https://ewwink.github.io/demo/script.js at line 10

click debugger continue button, you will see message variable "hijacked..."

the code:

```<code>// Copyright (c) 2011 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
// mod by ewwink

var attachedTabs = {};
var version = "1.1";

chrome.debugger.onEvent.addListener(onEvent);
chrome.debugger.onDetach.addListener(onDetach);

chrome.browserAction.onClicked.addListener(function(tab) {
  var tabId = tab.id;
  var debuggeeId = {
    tabId: tabId
  };

  if (attachedTabs[tabId] == "pausing")
    return;

  if (!attachedTabs[tabId])
    chrome.debugger.attach(debuggeeId, version, onAttach.bind(null, debuggeeId));
  else if (attachedTabs[tabId])
    chrome.debugger.detach(debuggeeId, onDetach.bind(null, debuggeeId));
});

function onAttach(debuggeeId) {
  if (chrome.runtime.lastError) {
    alert(chrome.runtime.lastError.message);
    return;
  }

  var tabId = debuggeeId.tabId;
  chrome.browserAction.setIcon({
    tabId: tabId,
    path: "debuggerPausing.png"
  });
  chrome.browserAction.setTitle({
    tabId: tabId,
    title: "Pausing JavaScript"
  });
  attachedTabs[tabId] = "pausing";
  chrome.debugger.sendCommand(
    debuggeeId, "Debugger.enable", {},
    onDebuggerEnabled.bind(null, debuggeeId));
}

function onDebuggerEnabled(debuggeeId) {
  chrome.debugger.sendCommand(debuggeeId, "Debugger.setBreakpointByUrl", {
    lineNumber: 10,
    url: 'https://ewwink.github.io/demo/script.js'
  });
}

function onEvent(debuggeeId, method, params) {
  var tabId = debuggeeId.tabId;
  if (method == "Debugger.paused") {
    attachedTabs[tabId] = "paused";
    var frameId = params.callFrames[0].callFrameId;
    chrome.browserAction.setIcon({
      tabId: tabId,
      path: "debuggerContinue.png"
    });
    chrome.browserAction.setTitle({
      tabId: tabId,
      title: "Resume JavaScript"
    });
    chrome.debugger.sendCommand(debuggeeId, "Debugger.setVariableValue", {
      scopeNumber: 0,
      variableName: "changeMe",
      newValue: {
        value: 'hijacked by Extension'
      },
      callFrameId: frameId
    });
  }
}

function onDetach(debuggeeId) {
  var tabId = debuggeeId.tabId;
  delete attachedTabs[tabId];
  chrome.browserAction.setIcon({
    tabId: tabId,
    path: "debuggerPause.png"
  });
  chrome.browserAction.setTitle({
    tabId: tabId,
    title: "Pause JavaScript"
  });
}
</code>```

demo

Body:
I am trying to control the debugger using Chrome Extension.

I am using devtools-protocol and chrome extension documentation, but I have no idea how to implement them as I have not seen any samples of the methods in use. I used the sample extension from here which shows how to pause and resume the debugger only, but that's absolutely no use to me. I tried to implement some methods in the sample, but nothing happens.

function onDebuggerEnabled(debuggeeId) {
  chrome.debugger.sendCommand(debuggeeId, "Debugger.setBreakpointByUrl", {
        lineNumber: 45825,
        url: 'full https link to the js file from source tab'
  });
}

The problem is that the js file I am trying to debug is loaded from the website inside the sources tab and it's huge, we talking 150k+ lines after its been formatted and it takes some time to load.

Now can anyone tell me how to simply add a break point inside the js file from the sources (USING CHROME EXTENSION) so it could be triggered on action which will then stops the debugger so I could change values etc?

Body:
Maybe you are placing wrong breakpoint location (formatted source), try working with original source and add columnNumber: integer

and here working version JavaScript pause/resume -> background.js:

install this extension

open https://ewwink.github.io/demo/Debugger.setBreakpointByUrl.html

click debugger pause button

click button "Debug Me!"

it will hit breakpoint on https://ewwink.github.io/demo/script.js at line 10

click debugger continue button, you will see message variable "hijacked..."

the code:

// Copyright (c) 2011 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
// mod by ewwink

var attachedTabs = {};
var version = "1.1";

chrome.debugger.onEvent.addListener(onEvent);
chrome.debugger.onDetach.addListener(onDetach);

chrome.browserAction.onClicked.addListener(function(tab) {
  var tabId = tab.id;
  var debuggeeId = {
    tabId: tabId
  };

  if (attachedTabs[tabId] == "pausing")
    return;

  if (!attachedTabs[tabId])
    chrome.debugger.attach(debuggeeId, version, onAttach.bind(null, debuggeeId));
  else if (attachedTabs[tabId])
    chrome.debugger.detach(debuggeeId, onDetach.bind(null, debuggeeId));
});

function onAttach(debuggeeId) {
  if (chrome.runtime.lastError) {
    alert(chrome.runtime.lastError.message);
    return;
  }

  var tabId = debuggeeId.tabId;
  chrome.browserAction.setIcon({
    tabId: tabId,
    path: "debuggerPausing.png"
  });
  chrome.browserAction.setTitle({
    tabId: tabId,
    title: "Pausing JavaScript"
  });
  attachedTabs[tabId] = "pausing";
  chrome.debugger.sendCommand(
    debuggeeId, "Debugger.enable", {},
    onDebuggerEnabled.bind(null, debuggeeId));
}

function onDebuggerEnabled(debuggeeId) {
  chrome.debugger.sendCommand(debuggeeId, "Debugger.setBreakpointByUrl", {
    lineNumber: 10,
    url: 'https://ewwink.github.io/demo/script.js'
  });
}

function onEvent(debuggeeId, method, params) {
  var tabId = debuggeeId.tabId;
  if (method == "Debugger.paused") {
    attachedTabs[tabId] = "paused";
    var frameId = params.callFrames[0].callFrameId;
    chrome.browserAction.setIcon({
      tabId: tabId,
      path: "debuggerContinue.png"
    });
    chrome.browserAction.setTitle({
      tabId: tabId,
      title: "Resume JavaScript"
    });
    chrome.debugger.sendCommand(debuggeeId, "Debugger.setVariableValue", {
      scopeNumber: 0,
      variableName: "changeMe",
      newValue: {
        value: 'hijacked by Extension'
      },
      callFrameId: frameId
    });
  }
}

function onDetach(debuggeeId) {
  var tabId = debuggeeId.tabId;
  delete attachedTabs[tabId];
  chrome.browserAction.setIcon({
    tabId: tabId,
    path: "debuggerPause.png"
  });
  chrome.browserAction.setTitle({
    tabId: tabId,
    title: "Pause JavaScript"
  });
}

demo


问:
MPI: Canceling Non-blocking Send
I'm using Open MPI library to implement the following algorithm: we have two processes p1 and p2. They're both executing some iterations and at the end of each iteration, they communicate their results. The problem is that the execution is not necessarily balanced, so p1 may execute 10 iterations in the time p2 executes 1. Even though, I want p2 to read the latest result from the last iteration executed by p1.

Thus, my idea is that p1 sends its results at each iteration. But, before sending the result from an iteration i, it should check if p2 actually read the information from iteration i-1. If not, it should cancel the previous send so that when p2 reads from p1, it will  read the most recent result.

Unfortunately, I'm not sure how to do that. I've tried using MPI_Cancel, as in the following code:

```<code>int main (int argc, char *argv[]){

    int myrank, numprocs;
    MPI_Status status;
    MPI_Request request;

    MPI_Init(&argc, &argv);
    MPI_Comm_size(MPI_COMM_WORLD, &numprocs);
    MPI_Comm_rank(MPI_COMM_WORLD, &myrank);

    if(myrank == 0){
        int send_buf = 1, flag;
        MPI_Isend(&send_buf, 1, MPI_INT, 1, 123, MPI_COMM_WORLD,
                  &request);
        MPI_Cancel(&request);
        MPI_Wait(&request, &status);
        MPI_Test_cancelled(&status, &flag);
        if (flag) printf("Send cancelled\n");
        else printf("Send NOT cancelled\n");
        send_buf = 2;
        MPI_Isend(&send_buf, 1, MPI_INT, 1, 123, MPI_COMM_WORLD,
                  &request);
    }
    else {
        sleep(5);
        int msg;
        MPI_Recv(&msg, 1, MPI_INT, 0, 123,
                 MPI_COMM_WORLD, &status);
        printf("%d\n", msg);
    }
    MPI_Finalize();

    return 0;
}
</code>```

But when I execute, it says that the send could not be cancelled and p2 prints 1 instead of 2.

I'd like to know if there's any way to achieve what I'm proposing or if there's an alternative to code the behaviour between p1 and p2.

答:
Another approach entirely would be to use MPI one-sided communications. Note however that doing the passive communications, which is what you really want here, is fairly tricky (although pairwise, with mpi_win_post and mpi_win_start is easier) and that the one-sided stuff will hopefully all change in MPI-3, so I don't know how far down that road I would advise you to go.

More directly related to your first attempt here: rather than cancelling messages (which, as suggested above, is pretty drastic), it's probably much easier just to go through all queued messages (MPI guarantees that messages will not overtake each other - the only caveat is if you are using MPI_THREAD_MULTIPLE and having multiple threads sending within one MPI task in which case order is poorly defined):

```<code>#include <stdio.h>
#include <mpi.h>
#include <stdlib.h>
#include <unistd.h>
#include <math.h>

void compute() {
    const int maxusecs=500;
    unsigned long sleepytime=(unsigned long)round(((float)rand()/RAND_MAX)*maxusecs);

    usleep(sleepytime);
}

int main(int argc, char** argv)
{
  int rank, size, i;
  int otherrank;
  const int niters=10;
  const int tag=5;
  double newval;
  double sentvals[niters+1];
  double othernewval;
  MPI_Request reqs[niters+1];
  MPI_Status stat;
  int ready;

  MPI_Init(&argc, &argv);
  MPI_Comm_rank(MPI_COMM_WORLD, &rank);
  MPI_Comm_size(MPI_COMM_WORLD, &size);
  if (size != 2) {
     fprintf(stderr,"This assumes 2 processes\n");
     MPI_Finalize();
     exit(-1);
  }

  otherrank = (rank == 0 ? 1 : 0);
  srand(rank);

  compute();
  newval = rank * 100. + 0;
  sentvals[0] = newval;
  MPI_Isend(&(sentvals[0]), 1, MPI_DOUBLE, otherrank, tag, MPI_COMM_WORLD, &(reqs[0]));
  MPI_Recv (&othernewval,   1, MPI_DOUBLE, otherrank, tag, MPI_COMM_WORLD, &stat);
  for (i=0; i<niters; i++) {

      MPI_Iprobe(otherrank, tag, MPI_COMM_WORLD, &ready, &stat);
      while (ready) {
          MPI_Recv(&othernewval, 1, MPI_DOUBLE, otherrank, tag, MPI_COMM_WORLD, &stat);
          printf("%s[%d]: Reading queued data %lf:\n",
                  (rank == 0 ? "" : "\t\t\t\t"), rank, othernewval);
          MPI_Iprobe(otherrank, tag, MPI_COMM_WORLD, &ready, &stat);
      }

      printf("%s[%d]: Got data %lf, computing:\n",
              (rank == 0 ? "" : "\t\t\t\t"), rank, othernewval);
      compute();

      /* update my data */
      newval = rank * 100. + i + 1;
      printf("%s[%d]: computed %lf, sending:\n",
              (rank == 0 ? "" : "\t\t\t\t"), rank, newval);
      sentvals[i+1] = newval;
      MPI_Isend(&(sentvals[i+1]), 1, MPI_DOUBLE, otherrank, tag, MPI_COMM_WORLD, &(reqs[0]));
   }

  MPI_Finalize();

  return 0;
}
</code>```

Running this gives you (notice that just because data is sent doesn't mean its received at time of printing):

```<code>[0]: Got data 100.000000, computing:
                                [1]: Got data 0.000000, computing:
[0]: computed 1.000000, sending:
[0]: Got data 100.000000, computing:
                                [1]: computed 101.000000, sending:
                                [1]: Got data 0.000000, computing:
[0]: computed 2.000000, sending:
[0]: Got data 100.000000, computing:
                                [1]: computed 102.000000, sending:
                                [1]: Reading queued data 1.000000:
                                [1]: Got data 1.000000, computing:
[0]: computed 3.000000, sending:
[0]: Reading queued data 101.000000:
[0]: Got data 101.000000, computing:
                                [1]: computed 103.000000, sending:
                                [1]: Reading queued data 2.000000:
                                [1]: Got data 2.000000, computing:
[0]: computed 4.000000, sending:
                                [1]: computed 104.000000, sending:
[0]: Reading queued data 102.000000:
                                [1]: Reading queued data 3.000000:
                                [1]: Got data 3.000000, computing:
[0]: Got data 102.000000, computing:
[0]: computed 5.000000, sending:
[0]: Reading queued data 103.000000:
[0]: Got data 103.000000, computing:
                                [1]: computed 105.000000, sending:
                                [1]: Reading queued data 4.000000:
                                [1]: Got data 4.000000, computing:
[0]: computed 6.000000, sending:
[0]: Reading queued data 104.000000:
[0]: Got data 104.000000, computing:
                                [1]: computed 106.000000, sending:
                                [1]: Reading queued data 5.000000:
                                [1]: Got data 5.000000, computing:
[0]: computed 7.000000, sending:
[0]: Reading queued data 105.000000:
[0]: Got data 105.000000, computing:
                                [1]: computed 107.000000, sending:
                                [1]: Reading queued data 6.000000:
                                [1]: Got data 6.000000, computing:
[0]: computed 8.000000, sending:
[0]: Reading queued data 106.000000:
[0]: Got data 106.000000, computing:
                                [1]: computed 108.000000, sending:
                                [1]: Reading queued data 7.000000:
                                [1]: Got data 7.000000, computing:
[0]: computed 9.000000, sending:
[0]: Reading queued data 107.000000:
[0]: Got data 107.000000, computing:
                                [1]: computed 109.000000, sending:
                                [1]: Reading queued data 8.000000:
                                [1]: Got data 8.000000, computing:
[0]: computed 10.000000, sending:
                                [1]: computed 110.000000, sending:
</code>```

Note that this is just demonstration code, a final version really needs to do waitalls and more iprobes at the end there to free any pending requests and flush any waiting messages.

Title: MPI: Canceling Non-blocking Send

Body:
I'm using Open MPI library to implement the following algorithm: we have two processes p1 and p2. They're both executing some iterations and at the end of each iteration, they communicate their results. The problem is that the execution is not necessarily balanced, so p1 may execute 10 iterations in the time p2 executes 1. Even though, I want p2 to read the latest result from the last iteration executed by p1.

Thus, my idea is that p1 sends its results at each iteration. But, before sending the result from an iteration i, it should check if p2 actually read the information from iteration i-1. If not, it should cancel the previous send so that when p2 reads from p1, it will  read the most recent result.

Unfortunately, I'm not sure how to do that. I've tried using MPI_Cancel, as in the following code:

int main (int argc, char *argv[]){

    int myrank, numprocs;
    MPI_Status status;
    MPI_Request request;

    MPI_Init(&argc, &argv);
    MPI_Comm_size(MPI_COMM_WORLD, &numprocs);
    MPI_Comm_rank(MPI_COMM_WORLD, &myrank);

    if(myrank == 0){
        int send_buf = 1, flag;
        MPI_Isend(&send_buf, 1, MPI_INT, 1, 123, MPI_COMM_WORLD,
                  &request);
        MPI_Cancel(&request);
        MPI_Wait(&request, &status);
        MPI_Test_cancelled(&status, &flag);
        if (flag) printf("Send cancelled\n");
        else printf("Send NOT cancelled\n");
        send_buf = 2;
        MPI_Isend(&send_buf, 1, MPI_INT, 1, 123, MPI_COMM_WORLD,
                  &request);
    }
    else {
        sleep(5);
        int msg;
        MPI_Recv(&msg, 1, MPI_INT, 0, 123,
                 MPI_COMM_WORLD, &status);
        printf("%d\n", msg);
    }
    MPI_Finalize();

    return 0;
}

But when I execute, it says that the send could not be cancelled and p2 prints 1 instead of 2.

I'd like to know if there's any way to achieve what I'm proposing or if there's an alternative to code the behaviour between p1 and p2.

Body:
Another approach entirely would be to use MPI one-sided communications. Note however that doing the passive communications, which is what you really want here, is fairly tricky (although pairwise, with mpi_win_post and mpi_win_start is easier) and that the one-sided stuff will hopefully all change in MPI-3, so I don't know how far down that road I would advise you to go.

More directly related to your first attempt here: rather than cancelling messages (which, as suggested above, is pretty drastic), it's probably much easier just to go through all queued messages (MPI guarantees that messages will not overtake each other - the only caveat is if you are using MPI_THREAD_MULTIPLE and having multiple threads sending within one MPI task in which case order is poorly defined):

#include <stdio.h>
#include <mpi.h>
#include <stdlib.h>
#include <unistd.h>
#include <math.h>

void compute() {
    const int maxusecs=500;
    unsigned long sleepytime=(unsigned long)round(((float)rand()/RAND_MAX)*maxusecs);

    usleep(sleepytime);
}

int main(int argc, char** argv)
{
  int rank, size, i;
  int otherrank;
  const int niters=10;
  const int tag=5;
  double newval;
  double sentvals[niters+1];
  double othernewval;
  MPI_Request reqs[niters+1];
  MPI_Status stat;
  int ready;

  MPI_Init(&argc, &argv);
  MPI_Comm_rank(MPI_COMM_WORLD, &rank);
  MPI_Comm_size(MPI_COMM_WORLD, &size);
  if (size != 2) {
     fprintf(stderr,"This assumes 2 processes\n");
     MPI_Finalize();
     exit(-1);
  }

  otherrank = (rank == 0 ? 1 : 0);
  srand(rank);

  compute();
  newval = rank * 100. + 0;
  sentvals[0] = newval;
  MPI_Isend(&(sentvals[0]), 1, MPI_DOUBLE, otherrank, tag, MPI_COMM_WORLD, &(reqs[0]));
  MPI_Recv (&othernewval,   1, MPI_DOUBLE, otherrank, tag, MPI_COMM_WORLD, &stat);
  for (i=0; i<niters; i++) {

      MPI_Iprobe(otherrank, tag, MPI_COMM_WORLD, &ready, &stat);
      while (ready) {
          MPI_Recv(&othernewval, 1, MPI_DOUBLE, otherrank, tag, MPI_COMM_WORLD, &stat);
          printf("%s[%d]: Reading queued data %lf:\n",
                  (rank == 0 ? "" : "\t\t\t\t"), rank, othernewval);
          MPI_Iprobe(otherrank, tag, MPI_COMM_WORLD, &ready, &stat);
      }

      printf("%s[%d]: Got data %lf, computing:\n",
              (rank == 0 ? "" : "\t\t\t\t"), rank, othernewval);
      compute();

      /* update my data */
      newval = rank * 100. + i + 1;
      printf("%s[%d]: computed %lf, sending:\n",
              (rank == 0 ? "" : "\t\t\t\t"), rank, newval);
      sentvals[i+1] = newval;
      MPI_Isend(&(sentvals[i+1]), 1, MPI_DOUBLE, otherrank, tag, MPI_COMM_WORLD, &(reqs[0]));
   }

  MPI_Finalize();

  return 0;
}

Running this gives you (notice that just because data is sent doesn't mean its received at time of printing):

[0]: Got data 100.000000, computing:
                                [1]: Got data 0.000000, computing:
[0]: computed 1.000000, sending:
[0]: Got data 100.000000, computing:
                                [1]: computed 101.000000, sending:
                                [1]: Got data 0.000000, computing:
[0]: computed 2.000000, sending:
[0]: Got data 100.000000, computing:
                                [1]: computed 102.000000, sending:
                                [1]: Reading queued data 1.000000:
                                [1]: Got data 1.000000, computing:
[0]: computed 3.000000, sending:
[0]: Reading queued data 101.000000:
[0]: Got data 101.000000, computing:
                                [1]: computed 103.000000, sending:
                                [1]: Reading queued data 2.000000:
                                [1]: Got data 2.000000, computing:
[0]: computed 4.000000, sending:
                                [1]: computed 104.000000, sending:
[0]: Reading queued data 102.000000:
                                [1]: Reading queued data 3.000000:
                                [1]: Got data 3.000000, computing:
[0]: Got data 102.000000, computing:
[0]: computed 5.000000, sending:
[0]: Reading queued data 103.000000:
[0]: Got data 103.000000, computing:
                                [1]: computed 105.000000, sending:
                                [1]: Reading queued data 4.000000:
                                [1]: Got data 4.000000, computing:
[0]: computed 6.000000, sending:
[0]: Reading queued data 104.000000:
[0]: Got data 104.000000, computing:
                                [1]: computed 106.000000, sending:
                                [1]: Reading queued data 5.000000:
                                [1]: Got data 5.000000, computing:
[0]: computed 7.000000, sending:
[0]: Reading queued data 105.000000:
[0]: Got data 105.000000, computing:
                                [1]: computed 107.000000, sending:
                                [1]: Reading queued data 6.000000:
                                [1]: Got data 6.000000, computing:
[0]: computed 8.000000, sending:
[0]: Reading queued data 106.000000:
[0]: Got data 106.000000, computing:
                                [1]: computed 108.000000, sending:
                                [1]: Reading queued data 7.000000:
                                [1]: Got data 7.000000, computing:
[0]: computed 9.000000, sending:
[0]: Reading queued data 107.000000:
[0]: Got data 107.000000, computing:
                                [1]: computed 109.000000, sending:
                                [1]: Reading queued data 8.000000:
                                [1]: Got data 8.000000, computing:
[0]: computed 10.000000, sending:
                                [1]: computed 110.000000, sending:

Note that this is just demonstration code, a final version really needs to do waitalls and more iprobes at the end there to free any pending requests and flush any waiting messages.

ContentLicense: CC BY-SA 4.0